diff --git a/.cvsignore b/.cvsignore deleted file mode 100644 index 2c0a0803b5..0000000000 --- a/.cvsignore +++ /dev/null @@ -1,27 +0,0 @@ -goEnv* -dist -.classpath -build.properties -log4j-1.3alpha.jar -log4j-chainsaw-1.3alpha.jar -log4j-lf5-1.3alpha.jar -.project -IDEAS -velocity.log.1 -velocity.log -log4j-1.3alpha0.jar -log4j-chainsaw-1.3alpha0.jar -log4j-lf5-1.3alpha0.jar -chainsaw-bundle -chainsaw-bundle.zip -webstart-dependant-receivers.jar-1.3alpha.jar -.settings -log4j-1.3alpha-1.jar -log4j-chainsaw-1.3alpha-1.jar -log4j-1.3alpha-?.jar -log4j-chainsaw-1.3alpha-?.jar -ugli-*.jar -classes -bin -log4j-*.jar -tmp diff --git a/BRANCHES b/BRANCHES deleted file mode 100644 index da0e39d1ab..0000000000 --- a/BRANCHES +++ /dev/null @@ -1,61 +0,0 @@ - -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/HOWTOBUILD.txt b/HOWTOBUILD.txt deleted file mode 100644 index 0bc816eedc..0000000000 --- a/HOWTOBUILD.txt +++ /dev/null @@ -1,31 +0,0 @@ -HOWTOBUILD.txt -============== - -This document outlines the steps required to build and run the log4j sandbox classes. - -Comments/Changes/Bugs for this document and build process: - * Log4j Developers list (log4j-dev@logging.apache.org) - - -Assumptions -=========== -* Familiar with Ant, and have it installed (http://ant.apache.org/) - (requires the 1.5.x series of Ant, including Conditions support) - -Step-by-Step to build Log4j-Sandbox -====================================== - -1. Download logging-log4j (you've probably already done this if you're reading - this...) - -2. Copy the build.properties.sample file -> build.properties - -3. Edit the build.properties file and modify to suit your needs. In particular - * Ensure the "Library Path Stuff" section contains correct relative/full paths to the - relevant libraries (You might need to source these from the 'Net) - -4. From the logging-log4j root directory, type: - - ant jar - - That's it ;) \ No newline at end of file diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000000..fecdc441f7 --- /dev/null +++ b/INSTALL @@ -0,0 +1,104 @@ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +=========== +Using log4j +=========== + +1) First untar or unzip the distribution file. + +2) Assuming you chose to extract the distribution in to the + PATH_OF_YOUR_CHOICE, untarring the distribution file should create + a logging-log4j-VERSION directory, where VERSION is the log4j + version number, under PATH_OF_YOUR_CHOICE. We will refer to the + directory PATH_OF_YOUR_CHOICE/apache-log4j-VERSION/ as $LOG4J_HOME/. + +3) Add $LOG4J_HOME/log4j-VERSION.jar to your CLASSPATH, + +4) You can now test your installation by first compiling the following + simple program. + + import org.apache.log4j.Logger; + import org.apache.log4j.BasicConfigurator; + + public class Hello { + + private static final Logger logger = Logger.getLogger(Hello.class); + + public + static + void main(String argv[]) { + BasicConfigurator.configure(); + logger.debug("Hello world."); + logger.info("What a beatiful day."); + } + } + + + After compilation, try it out by issuing the command + + java Hello + + You should see log statements appearing on the console. + +5) Refer to the javadoc documentation and the user manual on how to + include log statements in your own code. + +========= +JAR files +========= + +The log4j distribution comes with one jar file: log4j-VERSION.jar +under the LOG4J_HOME directory. + +This jar file contains all the class files of the log4j project, +except test cases and classes from the "examples" and +"org.apache.log4j.performance" packages. + + +============== +Building log4j +============== + +log4j (as of 1.2.15) is built with Maven 2. To rebuild log4j, +place Maven 2 on the PATH and execute "mvn package". The resulting +jar will be placed in the target subdirectory. + +If building with JDK 1.4, one dependency will need to be manually +installed since its license does not allow it to be placed in the +online maven repositories. If not already installed, a build attempt will +describe where to download and how to install the dependency. To +install the dependency: + +Download JMX 1.2.1 from http://java.sun.com/products/JavaManagement/download.html. + +$ jar xf jmx-1_2_1-ri.zip +$ mvn install:install-file -DgroupId=com.sun.jmx -DartifactId=jmxri \ + -Dversion=1.2.1 -Dpackaging=jar -Dfile=jmx-1_2_1-bin/lib/jmxri.jar + + +The build script will attempt to build NTEventLogAppender.dll if +MinGW is available on the path. If the unit tests are run on Windows +without NTEventLogAppender.dll, many warnings of the missing DLL +will be generated. An installer for MinGW on Windows is +available for download at http://sourceforge.net/project/showfiles.php?group_id=2435. +MinGW is also available through the package managers of many Linux distributions. + +In case of problems send an e-mail note to +log4j-user@logging.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/INSTALL.txt b/INSTALL.txt deleted file mode 100644 index a04685359e..0000000000 --- a/INSTALL.txt +++ /dev/null @@ -1,175 +0,0 @@ - -=========== -Using log4j -=========== - -1) First untar or unzip the distribution file. - -2) Assuming you chose to extract the distribution in to the - PATH_OF_YOUR_CHOICE, untarring the distribution file should create - a logging-log4j-VERSION directory, where VERSION is the log4j - version number, under PATH_OF_YOUR_CHOICE. We will refer to the - directory PATH_OF_YOUR_CHOICE/logging-log4j-VERSION/ as $LOG4J_HOME/. - -3) Assuming you are using log4j version 1.3, add - $LOG4J_HOME/log4j-1.3.jar to your CLASSPATH, - -4) You can now test your installation by first compiling the following - simple program. - - import org.apache.log4j.Logger; - import org.apache.log4j.BasicConfigurator; - - public class Hello { - - static Logger logger = Logger.getLogger(Hello.class); - - public static void main(String argv[]) { - BasicConfigurator.configure(); - logger.debug("Hello world."); - logger.info("What a beatiful day."); - } - } - - - After compilation, try it out by issuing the command - - java Hello - - You should see log statements appearing on the console. - -5) Refer to the javadoc documentation and the user manual on how to - include log statements in your own code. - -========= -JAR files -========= - -The log4j distribution comes with several jar files under the -LOG4J_HOME/ directory. - -* log4j-VERSION.jar - - Contains the core log4j classes. It also includes UGLI API hardwired - to use log4j. - -* log4j-smtp.jar - - Contains SMTPAppender and associated classes. - -* log4j-oro.jar - - Contains LogFilePatternReceiver and LikeRule classes which are - dependent on jakarta-oro. - - SMTPAppender and associated classes. - -* log4j-xml.jar - - Contains several optional classes from the org.apache.log4j.xml package. - -* log4j-optional.jar - - Contains several optional appenders/receivers from the - org.apache.log4j.net package. - -* log4j-db.jar - - Contains DBAppender/DBReceiver and associated classes. - -* log4j-jms.jar - - Contains JMSAppender/JMSReceiver and associated classes. - -* ugli-nop.jar - - UGLI hardwired to use the NOP implementation. - -* ugli-simple.jar - - UGLI hardwired to use the SimpleLogger implementation. - -* ugli-jdk14.jar - - UGLI hardwired to use the java.util.logger package. - - -================== -log4j dependencies -================== - -Log4j is based on JDK 1.2 with the following additional requirements: - - ---------------------------- - Package org.apache.log4j.xml - ---------------------------- - - 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. - - The DOMConfigurator.configure(String filename) method and its variants - require a JAXP compatible XMLparser, for example the Apache Xerces - parser. Compiling the DOMConfigurator requires the presence of a - JAXP parser in the classpath. - - Given that Ant already ships with a compatible XML parser, you do - *not* need to worry about setting the parser when building, - i.e. compiling, log4j. - - ------------ - SMTPAppender - ------------ - - 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: - - http://java.sun.com/products/javamail/ - - and the JavaBeans Activation Framework at: - - http://java.sun.com/beans/glasgow/jaf.html - - ---------------------- - DBAppender/DB Receiver - ---------------------- - - DBAppender/DB Receiver have a dependency on the JDBC API. - - ----------- - JMSAppender - ----------- - - The JMSAppender requires the JMS API as well as JNDI. The JMS API - is usually bundled with the products of the vendors listed under - - http://java.sun.com/products/jms/vendors.html - - ----------------------- - JUnit testing framework - ----------------------- - - Log4j uses the JUnit framework version 3.7 for internal unit - 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 - -============== -Building log4j -============== - -Like most java appilicatios today, log4j relies on ANT as its build -tool. ANT is availale from "http://logging.apache.org/ant/". ANT -requires a build file called build.xml which is part of this -distribution. Required components from other projects are specified in -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@logging.apache.org. Please do not directly e-mail 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/KEYS b/KEYS index 09191f7bdd..743f2f3dfb 100644 --- a/KEYS +++ b/KEYS @@ -1,4 +1,5 @@ This file contains the PGP&GPG keys of various Apache developers. +This file contains the PGP&GPG keys of various Apache developers. Please don't use them for email unless you have to. Their main purpose is code signing. @@ -53,53 +54,23 @@ EQIABgUCQqoSPwAKCRASsodYDHxPBQ7wAKD4DO0Se4+SvSqUKDfxhI0lJTgK0gCg =GKga -----END PGP PUBLIC KEY BLOCK----- -Type bits keyID Date User ID -DSS 3072/1024 0x7C037D42 2003/08/05 *** DEFAULT SIGNING KEY *** - Yoav Shapira - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: PGP 6.5.8 - -mQGiBD8u/mgRBAD5WKD5xF3CLrnABeS1DvQQhYH+tJjvAmyZgFkYwaQT7eiiOzLa -PC5knbcBC4nuw+8OOPDFw0Ghb2MFogQzRxD6gpPH2t9eEUsrkPFax2Kw2vNTHRrQ -RGAastmi+EYJsQAoktX2dPseTdrkeJBk240Bfj08ZUFg4uPuho9C45ND6QCg/6SO -FMuan62QE+DwlUiMDo4ZcU0EAMDS8k6Dhb5m/0njO6w9OLTEyzohlsM9AP+4mfgB -NOJYhrzfkFoElOcWSA/V3nmYn2VS0oIYDDtBnjXVWZidzTAWKsbT9/AepS3/P2tG -KMhlXhas+uAiAbMpOglz8fdQ76ivQqyRdS99t4iy/cP2ZC3ShAqZQCacfWY5ZQ8Q -kTILBADvp/eayw8fvtfWQXJ9EjBRbhO4THmP6z8J+4ypG6l0V/RBjDWZybrqibO9 -ejnOjQYJNCnfrfpzQ5l6dHyy86zLyg+bkFxeId4jp/IfDfJX90sGbuQahNYYwqTp -SFiDMI3KN5ZhzhGnx+pKQh59pcux3HyKmcpPa4oB0CT828lWuLQfWW9hdiBTaGFw -aXJhIDx5b2F2c0BhcGFjaGUub3JnPokATgQQEQIADgUCPy7+aAQLAwECAhkBAAoJ -ECZhkcN8A31CGLkAoPRDGtLRwjkzS2F/OBPkRHKF9/atAKCIh3Fmcr2Cdn05P4qF -kBe3QeWVt7kDDQQ/Lv5qEAwAzB13VyQ4SuLE8OiOE2eXTpITYfbb6yUOF/32mPfI -fHmwch04dfv2wXPEgxEmK0Ngw+Po1gr9oSgmC66prrNlD6IAUwGgfNaroxIe+g8q -zh90hE/K8xfzpEDp19J3tkItAjbBJstoXp18mAkKjX4t7eRdefXUkk+bGI78KqdL -fDL2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoBp1ajFOmPQFXz0AfGy0Op -lK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnhV5JZzf24rnRPxfx2vIPF -RzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr5fSI/VhOSdvNILSd5JEH -NmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4XTjTNP18F1dDox0YbN4z -ISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWakXUGf -nHy9iUsiGSa6q6Jew1XpTDJvAAICC/4iJF383WNktP9/SxeGVIV74r7C7q5Cxr4a -Liy7pEYs52DEft3JzTCLI5O4+NjOw+hEd3QiIytUJRW66V6zd50h4x9lBfK+eMYz -GKNN7kd3aBmH/vXEsG9m9bK1ExwyWq4uyf76nRx1Ya9YthNWmxPUHQnSrOYNPU0/ -beA87ouZG4RL9tYqdu3NKJ4g/DYiaw+twvhSoCUkBEFHFfKLDlv8zyQvPTaPUSAM -Ha5/G2Dj1D5RluMSCEMG1V8+YcYAFh63WEP7Afye0mR1LMJvmlba67ogh0ZSfR+I -ju3lhJ9XOp/2W372F9ZbRJofgofVwHQV6INB5uX7KHAdXtPTss+l1nTmydLhsiPC -5oh99ITPdOm8gRzrP10aFwCnwsqXvr+b7fX/CywpuCOQMIr4sbhbYTTClwDo6E0U -TQ+Nb7PWE+8KuJuobTvMUqDQSQaQBnkpLcvRt3cPppANtkaADAeNf0RqKxxLlym4 -AltN8G8IMLtSJoH9xlQHTQA4tEUeKOeJAEYEGBECAAYFAj8u/moACgkQJmGRw3wD -fUJh7ACdE7QuMkzSbxEzTXnbkS61AUPy06QAoI5b613vrWeqg5Gz9C7TzG+FEEoh -=O17Z ------END PGP PUBLIC KEY BLOCK----- pub 1024D/2E114322 2005-06-11 [expires: 2010-06-10] Key fingerprint = A1A2 B554 6D43 31B2 A41E 1C07 BE16 C95D 2E11 4322 uid Curt Arnold -sig 3 2E114322 2005-06-11 Curt Arnold +sig 3 2E114322 2010-02-17 Curt Arnold sub 2048g/209ECE57 2005-06-11 [expires: 2010-06-10] sig 2E114322 2005-06-11 Curt Arnold +pub 4096R/70C9C3D0 2010-02-17 [expires: 2012-02-17] + Key fingerprint = 28F5 F554 39C7 1A8F 2B1E 58C4 D3EC 4990 70C9 C3D0 +uid carnold@apache.org (CODE SIGNING KEY) +sig 3 70C9C3D0 2010-02-17 carnold@apache.org (CODE SIGNING KEY) +sig 2E114322 2010-02-17 Curt Arnold +sub 4096R/0E434FF3 2010-02-17 [expires: 2012-02-17] +sig 70C9C3D0 2010-02-17 carnold@apache.org (CODE SIGNING KEY) + -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.1 (Darwin) +Version: GnuPG/MacGPG2 v2.0.14 (Darwin) mQGiBEKrSNQRBAC4J7udOBoC5+gVxBaPAbjXfnq12l5Pau1WD+UothePNGjI2hOp +Rnzikk3ISgyrjiX3A8ScZYbu3iXvMpF4zknkGLdmerpf4Gz9xGeushwun+UFaFL @@ -110,121 +81,228 @@ JlOH/8JJgC6eSwiUXJ0cOJwpMonitcpMLouxuURuPSpfE5b1mQ1gFzN5MBL8xlZQ 8IO6A/9qWwyWyQBoJud0RDIsVRosdoSBZtw9PHsURgsqfNsS2NXTWK4HjxExw1KO AXmRlALfrH8yAShy/AyiUrwlKHG2WPTe6Etygjlr4dIxqTiCOoi+qv+H8SXW4Qy3 SnyozJ2RlKoYG0oDTbVMsPhOFdytHjConDLL9vS14j4kN9zWB7QgQ3VydCBBcm5v -bGQgPGNhcm5vbGRAYXBhY2hlLm9yZz6IZAQTEQIAJAUCQqtI1AIbAwUJCWYBgAYL -CQgHAwIDFQIDAxYCAQIeAQIXgAAKCRC+FsldLhFDIs5CAJ9roOB39ithHoCLaDJx -l14efLwgNgCfcDBYutNX5W627kCeheDqhQbTqTi5Ag0EQqtJBRAIAN8maiGIO44S -dc9Ep3CAm0aXDeR8IQ/F253WcMQtkFBjeHEDd6/+EFT52vswMI6ZJDVV/A7pe4VM -XAdNutFmUG2gy9OJOu8gMuO3jTCLxUXyQYNF/RasOAQJgc7q1N5QgKtXVH2InQ21 -vHvlHM1fVe4rYDPr4JL2lZHe0P8kTzeQ7jI5pQnfYRJmS8I5AMQYFOiM48Pd7Sbs -Wu/rym7ikcmKUe6ZE59hSioneVP31CDMNRxCAQJVS1mZxTozsAEoh+cvmRjOD1Es -0iXvu6Sfe8+sLRL+7CNUZgixE1UFbdnNxuZGlG9qs0LGP7hDWijT1/Y4SHz4ovXx -k0oocmFtiLcAAwcIAMbY7K99hLAFVaU2ukxCSp1TNPcD+IB3gtpRieKaZvBn/LGe -CO+fNAogkw537lmpLk4nI+JiP/xWohyJ9lyEpW7yD4c9AHKNjqvEWD5Bhpnw4qKJ -ohQSVQwEeJRsftY4D0jCP9xbgPiq5woBzHWNok3BVaHqLK0fd0/+KygnT+k6cR22 -Mus9RsEisXk9Oj5lvC0miDOWof4vk2Ll8/H3xt4CXAr13n5Yj2632HolOHrFUQXT -gwc9v5CNIihOQMEiXFxHh743qbsUZktjxeYH7r8wSCV93/QQ4qELiWoUzndpkCRT -lEKenucAv6f5qqZqG7pVW8S48T99HwzwqgFX5VOITwQYEQIADwUCQqtJBQIbDAUJ -CWYBgAAKCRC+FsldLhFDIjnoAJ9ECOIrTH3adnVLOkHZnewyp2ssxwCgtLjlwZ7/ -4QtL3W5Id3nKxPFiI+c= -=9ut1 +bGQgPGNhcm5vbGRAYXBhY2hlLm9yZz6IZwQTEQIAJwIbAwUJCWYBgAIeAQIXgAUC +S3t0VgULCQgHAwUVCgkICwUWAgMBAAAKCRC+FsldLhFDIrS6AJ92lpskwBHNNWLw +XsHLaFSGh9n9tACfT0dOv3wec7oM+lt2x81S0uqcbZq5Ag0EQqtJBRAIAN8maiGI +O44Sdc9Ep3CAm0aXDeR8IQ/F253WcMQtkFBjeHEDd6/+EFT52vswMI6ZJDVV/A7p +e4VMXAdNutFmUG2gy9OJOu8gMuO3jTCLxUXyQYNF/RasOAQJgc7q1N5QgKtXVH2I +nQ21vHvlHM1fVe4rYDPr4JL2lZHe0P8kTzeQ7jI5pQnfYRJmS8I5AMQYFOiM48Pd +7SbsWu/rym7ikcmKUe6ZE59hSioneVP31CDMNRxCAQJVS1mZxTozsAEoh+cvmRjO +D1Es0iXvu6Sfe8+sLRL+7CNUZgixE1UFbdnNxuZGlG9qs0LGP7hDWijT1/Y4SHz4 +ovXxk0oocmFtiLcAAwcIAMbY7K99hLAFVaU2ukxCSp1TNPcD+IB3gtpRieKaZvBn +/LGeCO+fNAogkw537lmpLk4nI+JiP/xWohyJ9lyEpW7yD4c9AHKNjqvEWD5Bhpnw +4qKJohQSVQwEeJRsftY4D0jCP9xbgPiq5woBzHWNok3BVaHqLK0fd0/+KygnT+k6 +cR22Mus9RsEisXk9Oj5lvC0miDOWof4vk2Ll8/H3xt4CXAr13n5Yj2632HolOHrF +UQXTgwc9v5CNIihOQMEiXFxHh743qbsUZktjxeYH7r8wSCV93/QQ4qELiWoUzndp +kCRTlEKenucAv6f5qqZqG7pVW8S48T99HwzwqgFX5VOITwQYEQIADwUCQqtJBQIb +DAUJCWYBgAAKCRC+FsldLhFDIjnoAJ9ECOIrTH3adnVLOkHZnewyp2ssxwCgtLjl +wZ7/4QtL3W5Id3nKxPFiI+eZAg0ES3tyxgEQAMiGGFkj5EOkQv6EYFtWvd65Y6yn +dpNIbOb/o9SszVu4kO1OHdemWg4OwXERb1+Ozl9NamOvW0ypH8qzFu4rhpoiUev0 +DV93afBkhW6Mvd8D459okgnlfb/K7c3H72gHmuJKZkyNmLgyzX63BjgIbpjR83/N +RC578BjoJbYCe0bKR9bCE+MxxCQzUO+tcUrk8o00zEhqycmw1B7gFLWL5MAf50h8 +37/gbCcv9Q902kYfqsd5I7wPj4SRPnowN8vPlNtiwqMDqCl5rUmCrulfvSoNaJ/1 +bEu7L9+/ptontfnr3kMJksGsoPo+Cf8xkGZL1D+80TxrBRf4CILQRF8dm+K8+4ms +VMsPccCINw/AZh+GkIjJ+SfQpIE4Rx6OMd6JSmCuMnom4O8ZbJ9QYcuS1uf4r32M +C6MQZrENvEFj1MaSZoRPXNdI/vwCKE5Hc1enB7bEHD6yayE3SgIGYVC+YPJkh0Ch +fAANRSlw7arrL13UB6xwzAnzhIK7BzADsbGDMAMmIh+rvb6Xxb6iQCh/q7iGPpRz +AXkmusLsbk6hMP4d8W5puJQTdy7a4t2DIX//9LYpl+DeYCww9DbXTwIays/WLnpo +Jxj8R1G75gfUIC+kvFl+OiIOR7579yw5Ar35DmqG8RIwxW9cv+at3u63WhYwdhqB +4Dm5hujWYluYoAZvABEBAAG0OmNhcm5vbGRAYXBhY2hlLm9yZyAoQ09ERSBTSUdO +SU5HIEtFWSkgPGNhcm5vbGRAYXBhY2hlLm9yZz6JAjwEEwEKACYFAkt7csYCGwMF +CQPCZwAFCwkIBwMFFQoJCAsEFgIBAAIeAQIXgAAKCRDT7EmQcMnD0FNcD/oDWhmZ +sikg42VV4SnaaIGUgjHoNT5NKWHhgeEXWAu44Y1r9X0+a6/xvtr69MfbExn9CJWJ +6vuyY9bpLcNNB49NLxhKD/IEpAUdGYcGGn1+AkkX/Sa7Y2SE5F9snJ2aSn+BctdP +JNHgEQxWGXGHAFPEdw73RudqsDUvcIat+uU8H/ZdrXX1F2NiUp7rjHqYvizXgy5p +Es99n00gCiz3eKg2l816v1ClDRAufFDj/JHghL4Yx+wUJN0cFBOAZHzDZgtcSUuv +Jb2B2f31vjqJ5cGzSQ1KhRIqoIwUm+LYOtuCAbboW9P9GPbib6oavRXRbz/SAoIX +BbYGWnA4aYQGT1r/FrLHZOmY6kw2izOPryXXxu1qAblFDc1C6XNHtNWx3uuTE/TL +haePHai9N0rJLuJCwHSveY5Lc8LF6cE2sV+kFsyMUwzaxLHg4G2XpnVIx5mEM+Fr +Hb89t8rThdE2n+qwUgCzlYgNEjAb1wf/xqUwXL7r/3rwKYkamq7Y7ljY9BTRX6VY +XsDEiCPs2XSNQtZfTajkei/WN0/SJDQZfIbK9wPqQXTA4DxZ5qJaTa5hS/ueksYH +tCK6pH3L8ov92ZbDcfxwq3u9wGl3GT1abFIfyfX53FXaoCXSi+g7F+a3hv6nmy0E +1zT26YXh3xRIPJ2x8gGCATHsGHabfnrRespQeYhGBBARCgAGBQJLe3TDAAoJEL4W +yV0uEUMianUAn1+KjhbSeXIcMrxWK6WaCHojo0StAJ9GiDT+6t4AnRXCIJtob6uZ +tN17tLkCDQRLe3LGARAAq9WmSZRtHLuOG8gmYesNeyfPqTdOgak+dgT4nnMIMnlN +Y23k3oMIgSBeiYyFMDoTXPYsxVZW24mrMhi9D1XhsDygn534iD94ptrLpnDG+56z +0aHdGjS8eUhEK636uNLT47ZEm8997fWCiqQQzX7UP9ttP9DKLkseiZ97jtN5To+7 +n5Kmog082k0208p2jJqVw9aqoeXh4520nRaqiD2QQg2onQLCAz7UH7RllVzhqH9Z +G3HcI0RXw3q6FP33XlGNQuxhV9IPna9/43TXHaOsstwtJjvOaPfzGDS7BAmIKZx6 +rbL7VYcIheZ+qXuVoRrwb0facxJfkTcLUy8aRQappDxk9FpWByEK2hEsWiw+CkI6 +maFoyCvC/io5L3ZwWL3C+7wMZ1Qi8DvT93NbLboxhW5XRZk9gb1vlJSalTMbGNUV +tOiV+SbwfkMQX1xOMFbDx2u5orcJ0h9/Ox1LJEuoTHx68nXLB1e9ioLfQPATM+70 +JhXGAHmjp8rkY6Jdua0MbamQtUXfJAZv/pJrukWNWmT5UFYY0DNNcypfaqm0l4g9 +ZFwwUaraWrMkcsrvmmZ+6JASSwA1a6RwXYLtsMLX0boaUKEvDPqnIbeF3jJnztLN +MDWsGeW2NXYfuIaHMTUM7oVGgpDP+TG1IlOQU0lrSbw4Sm3AlA25tOF3jgGZtaMA +EQEAAYkCJQQYAQoADwUCS3tyxgIbDAUJA8JnAAAKCRDT7EmQcMnD0MzLEACRQ6Em +nkRbNupza9airUj2vrXj4I5ZN9jvgnvZcBVSmbKDEZR0akHFXaEes4d9AVh95y91 +HuOHiiJ1hUZ0TGlk52ML5FEE68dDxvORUven9DiUdTAgLBJ5rUvfzj3tf6R4BNmM +rzyEA0UCAthqTd1nCdjhwIT6z4BiEVGsBHVAN7mYl+blHqssvuRgNAWrdPFRGYJP +cXI7wQc051WCHWXzi6b4h7oiIwlfsx7818S7ITHGM1AxTFl5rIqs9K4oHFTbcg1g +sLbJFM0NJ4l1yQZG/9Vldo0RmDdMSc5KgwPa48nf8LHsL3qtcQuvy/b1CIhf8UqZ +OWabhVa25xQFTRPmN5ND6wAsvx/zYr0/NF7RfJ3gTn8jCif8LZLVtYYP8zj4TgIL +ZhP46YwxaLkyibh+7/R+obszGVt06yqefNYuzfAXpX+2/pDUVQ532AAVD5g4enX7 +eAxMda//UAC+WxfCqE6c3CWhXlGaborCsP5auhBg0rbi3/dgPySwMugBfVksa16X +X6y36kjw1MRZuhJi4WQGRLX4yjd6sGnWDoY5c/4G89JZKzjWsuNrSJIZRWrzgn84 +NLAXpK81RMPkWukePN4ZQ1WEi0IH6AbBBbmQhIRR1bnGR48ZXH+/piJTNi9yKOPi +wlp15dJcNo0puq0ZbuZjPboQjg8PQaGtlMVN6A== +=EKia -----END PGP PUBLIC KEY BLOCK----- - -pub 1024D/47C4113E 2004-06-24 - Key fingerprint = 2503 F500 644F DECD C5DC C38D B35E 96D7 47C4 113E -uid Jacob Kjome -sig 3 47C4113E 2005-06-24 Jacob Kjome -uid Jacob Kjome -sig 3 47C4113E 2005-06-24 Jacob Kjome -uid Jacob Kjome -sig 47C4113E 2004-06-24 Jacob Kjome -sig 3 47C4113E 2004-10-02 Jacob Kjome -sub 4096g/4E44B60C 2004-06-24 -sig 47C4113E 2004-06-24 Jacob Kjome +pub 4096R/F95275D4 2010-10-27 +uid Scott Deboy (CODE SIGNING KEY) +sig 3 F95275D4 2010-10-27 Scott Deboy (CODE SIGNING KEY) +sub 4096R/FC1C7FAC 2010-10-27 +sig F95275D4 2010-10-27 Scott Deboy (CODE SIGNING KEY) -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.1 (MingW32) -Comment: GnuPT 2.6.2.1 by EQUIPMENTE.DE - -mQGiBEDaU1cRBADahTOIBOcOb0gR9bH1CNUvkv4tyz+Dmeju1hhjOo0xz9JRyDal -2lo7IoKH7OkS4emv+rDVEVtAs2xuA0POR7L4kf8hiEfHVcSFi20NewcosKBWzdQ/ -1LNJg/woWTWlUikcBpdeXhsDL1T0/bNg7cnG1kpOEEbsHNME3xlFiMiPMwCg/2Qh -/iucIfZDx/1iITQIf3XtY5kEAIeLUviOdgm9+QBKAJgwTRlD0WMgU1IoZT5qoaMR -4S5uFhUyYVAc7JPuWcnXQ2Q/cRrV+92AfT6Fve/3u0FeuRtUq+HBLcF0ffaIDcU/ -5C+k4BvgiLOSX1p7P3gI5gjkusxbGTmX8UsbybvKjpa1jmL/TXIKdEO4yJ7yjoDK -UsbIA/9V+6h/WPS5t/CYrX4x6ofA+OxclXnEj6J8or3sjzAE8Wmp36XaoxqEDMQm -/60/BdISvS3nJMBAGDCkXeyCOevpObKBjq4OwWcyjpAoI9ntbsEYrsssf1RjoF0q -S1Hkc7YcKo6YJKYCxsszJIScR861yinMx1oRMx5ybFU+gryVGrQdSmFjb2IgS2pv -bWUgPGhvanVAYXBhY2hlLm9yZz6IXgQTEQIAHgUCQrtvagIbAwYLCQgHAwIDFQID -AxYCAQIeAQIXgAAKCRCzXpbXR8QRPpI0AKC2K3LpuC6hXMkPIXakmL2roMvLYQCf -XF+lnGtFwJwZT06fxcl/f7uU9W+0JEphY29iIEtqb21lIDxKYWNvYi5Lam9tZUBo -b3Rwb3AuY29tPohdBBARAgAdBQJA2lNXBwsJCAcDAgoCGQEFGwMAAAAFHgEAAAAA -CgkQs16W10fEET5LNgCg90G2fCgqcwROhwHALim2UFiVZFsAoMIb8P8MUb2AARp1 -OSsXKPa96/ZtiFwEExECABwFAkFeAMICGwMECwcDAgMVAgMDFgIBAh4BAheAAAoJ -ELNeltdHxBE+yWYAn3VlS8NWLzbRrmC2C70WyKMXypjTAKCYI800EZWcJ5J8lnYV -J1/q7w1/ybQbSmFjb2IgS2pvbWUgPGhvanVAdmlzaS5jb20+iF4EExECAB4FAkK7 -cKsCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQs16W10fEET6LZQCfQ1s8jdzP -MM40iGgzWF+Kh2yprFAAnj2fbuoVlWngPeP5W3WojcQFkIuuuQQNBEDaU1cQEAD5 -GKB+WgZhekOQldwFbIeG7GHszUUfDtjgo3nGydx6C6zkP+NGlLYwSlPXfAIWSIC1 -FeUpmamfB3TT/+OhxZYgTphluNgN7hBdq7YXHFHYUMoiV0MpvpXoVis4eFwL2/hM -TdXjqkbM+84X6CqdFGHjhKlP0YOEqHm274+nQ0YIxswdd1ckOErixPDojhNnl06S -E2H22+slDhf99pj3yHx5sHIdOHX79sFzxIMRJitDYMPj6NYK/aEoJguuqa6zZQ+i -AFMBoHzWq6MSHvoPKs4fdIRPyvMX86RA6dfSd7ZCLQI2wSbLaF6dfJgJCo1+Le3k -XXn11JJPmxiO/CqnS3wy9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadW -oxTpj0BV89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeS -Wc39uK50T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0 -iP1YTknbzSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF04 -0zT9fBdXQ6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQ -ClCbAkbTCD1mpF1Bn5x8vYlLIhkmuquiXsNV6z3WFwACAhAA9Wuh1hV1QZIVoQDT -1MLk9OkTIOS2xjc4saF+/NOLC/cZXC5ReCiuC/80MMPoUiK/V+oXbPsyG1eYZVOr -6KyObm7bP30PU+0gOuHsYkGAZQXGq4cZneDkX38mHHVVAg0xsuvM+BHWAJ0FRE69 -OHjZ9ow8oH9dYik6FGRnOrtMsSMUVF2Npk7fM6gOOc8Tthqg4awcmm/nn/7xsIrM -EzDZ3N3HA68iDxH+vA0PxHemECvF0bYP4lW8o9ZP36MFDJrsIcTdVlInIJxLCRex -y/+NTdCeHPQNptYoZKoI+S1Ay9M7z3N5dj5qWZ0u/Vy8yCuIGyCozbYqEgxo/9nq -TBe8TWXHu/qqJE5IFLl8ViacfP5nksSQUAdWRabai/Seguu1Se0JOsTe5hoPS3nk -bY+YcuQsvfA/7Qu4MmzEN4SxwkYs+qlny6HSoiH9hnEdMlvSwY0a8bnKlBWGF73X -60cuso6Rsd3rzqibYLuASemPDSBom2b2pi/vIBQcwLr+reBe39xD3WmZRlAvMlnh -uS2kc1r/mwFgnvY4QEKYTX6GE91KSDuCHvq1LYbjPKkRr2LDegkoEO4f3oWuXZ43 -nddGNpRqFOVXxlEhbhluOgUougY9PyJgyaRP5hwHQfYsedgdyIEb1qtoKoyhNsXO -uBj+I72TcaBoNc0xcGa9CNE84FWITAQYEQIADAUCQNpTVwUbDAAAAAAKCRCzXpbX -R8QRPlzhAKDYkXs1ip1eaPnnfZXAf4CMCaUTSACgoT3g+W3v47o4LAL6J2+aXuxM -HCA= -=br+o +Version: GnuPG v2.0.13 (Darwin) + +mQINBEzHvBgBEACRXXPHv5LNRuQRjz2SkKjxMLmP+jqzKJ/iqbXjfdKSvfStI+8K +9F6HW7FFOvST14bhC6FIyVAJya8hm06ge2Qyg/VkxdxdI7A2rNZpqbF3mdohwJmk +BtEbnU6KtLVV2kmi+U3aFwk8KEU6vbfta3XXd0oLWH5yDDaRhUUFmPqNQjp/Ivzc +M2NwMf2lnJbAWwTpGrXmWOqeUaKaOg+wLQMjXoupDENRir7IOsIL0AAm84ghaLi/ +MaVxBORnUsbq9mD9q7W6+0EFjun+Gh4WMualhTW1DZnZRFrCEcKkg5l5nM50DR40 +KDlKcpvgDJFn+FIR8Bq3qVasqvsKCyI8FTYWtcUMUOOdCaowrRWRfvgrrUd07lrQ +kzf2iH9POy1IMbk7Tx1Qhh9nSdZtLABeoFOQUoihsm6Gm2zohld/iNyTtDDW6WT1 +92SatUz7qSDJ+qrhhc+O5FZYqzrmWAxJs+sHXkEUUtfEXEq0bdy/uh2uO4bm3WbK +luXUXn6OJgGpICqtI5CiK1TwS2q8NHc9bFI4FF6drKE+bo/nz+q+ly67g3pa+Wtn +/q6rTTqxcRF0yr4StxONrgSVMqderIbwlOuCtBodRnVciJBgr+zX2kblnIDLF3a1 +qxcrdeMJ7bh7e3yMDmd+t+hoHnaRSMyhqBnFRpRJU7WQPxJNGrxy+H1djQARAQAB +tDJTY290dCBEZWJveSAoQ09ERSBTSUdOSU5HIEtFWSkgPHNkZWJveUBhcGFjaGUu +b3JnPokCNwQTAQoAIQUCTMe8GAIbAwULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAK +CRDoZBtF+VJ11ONRD/wKr3kIhBzCfDqKv/vjWHj/5eAnLwT2SohWnnuqIJG7w+ES +4D0LBBvHJHd2ssGs/UpujFQppsZ16rWm7n1/sZH9YGlFyEXqTnssLwDGqZlUUPyy +5aETRzaanbtNV7tgc8lZCMv2wDheMiVPmgJ7nkAkd5oTEfoKnnMO31NGoxbqJ5WW +95hm/Mx9v16oub/wh1yEMOIgGeCfrM3M9tpYq3651fAcLLPnzl7Z8abPcelEUQK3 +3Eo8CN3FZUizltDhutBCSlJgT1yt2x0LvvUJ9sKKN+uwRwDPmjaOsJIB8+L9FxSi +nxAtUUDG4DpuB7ck0x8V+v9Ny4tgnnxtgP9kCuwL1IzJ4PjC5Jw3bVC1rwHKO0uU +Sht/AUJV0lJLK3CISI+TfeKniOeIMrek424EqlPq0egrinNoS0T/3kF9GS14Oy9Q +8paGnOydMKjAg/e/2gNucG+bC44mZsxbwByKFwIXfplPaZaTxd6sHSIMUUTpe1tW +vQi4a349kPs1DkO0nu8c1WOdieVoQ2pz753ASAgQfaLx0tjrabczrz5W1GdtzK0H +uhrROlJR21M1W3YWglydUWETDaenOoGAkhQIFxZbae3PNf+T3lNrQztb3HSC4P/W +QyhodEYrxKgKLnMWSQZWMPEFGgSguZt0+q5T1xOTvxfdTrKemFeanlESDb3Q4rkC +DQRMx7wYARAA5M1zeDrEfVRc563s8WK95iAmrBoC+Ns9nuSHB5RSx+NFRUQATLvh +sR3UYINQpgQu3YA+TJt+rv5G7UpsBXCZ1b87IBJ8wJqLYTY3lt48OFwdt88AxJuw +xoDn06A78CNiqwJbRFV8MkaoZ2uNO+TVsFwfIF4J+zsTmbxcnW/oWoEP/stk9aH+ +sLjIaWI/DeTNeCRsro50X3uojxeQ+xvSDIbgO+siZrvAcjdoI7PAgx5vQSn3P8tw +hDGRokKm/Gxrww2s00SWTcI3jV/dhtHF+Rq2AJJOlwTpQ/gydJagioAgRd5gcRAa +Lz5DmNV3ZzPtibXjxpO3BfCTXs8B5k4JSNP3XEw0gus2aB2fTUmHeS04MFo5dOOX +njIpjqgruY6FPRT5UjwqT57a5XWdry0RrPQp6dqouDjs0rO+DB8Q3teniXqkkzIj +bExKSapV1Lp9OIKNkMeDeJ7T/o39LntlVe0Tnh5tKQSsi3KwAFWdT/WgaSYn6j3+ +1nlD1f5RkWVGjbcG6PVWi3j8QBvuKYQV3kOFew5ryrNrKT9tsgoYFRpGEshxxbLI +A+GnElaYm8CmaYlP+ddNzMxlFBT81zcqDes1ZhLRQbO14AYSJmrH8nsursoetzr0 +H8lkpkYQYoSjfu2sbEI1DNJ/ODjtdgPKEm9Q1MIFpkS/VYVlSHIqsLcAEQEAAYkC +HwQYAQoACQUCTMe8GAIbDAAKCRDoZBtF+VJ11BLMD/0QV+Tjh2fydHJ8AePWf+fR +MoE3lPZmSVJLyWoH4qQp2eWrOojpHUHGOjs2UUCxKvvxP37ATwD2AGv3uVfXDACD +KOD2UOB7fNrcBM26txI9hff+wUyJOx9LchRyfZFiXHXy0qm0j+pX4IgqxcWYNtJM +Xpjc4G5MKZjvdaqsUJ0718ukTo/i4S2+bx3mqO14jr/O/AxKWRIK1IMKyIncV9YQ +e9XX3bzBg1AC8CgnPqrsYZ64fcWk3AqsHoP9mkgD4cVsY4aVR+aUHrssWZoYb9mE +5Wgp59fggaldDIpa2SlNNzBl9m0KotRkGt73nVVMYzM4hUK810S9u41tAR4mJ+gj +jAaIjMjLLnYU1suxmDm/+DNaAkZ8cpwvGBGWCfm638aYQL/FqANygWCcpWGaNkdN +R73ZyGCSeWFBLrHM0OX26NiDgjYEtPi8V8TQ0th3qnWWUqkMTB3jUNUafHZnL56o +0PBtB/oOEW4qK31fjM/fnl86SItvZ276xhkrpzw1lHsvIi60Xzev2jdAbGZId73k +XpZ88gue4SdRe2+hT2SVZepfZBIUPwK0Fc3SlvFmWLCM6NLrqB6HbfvKYxXtbKsk +NR4RyqRdl9QfwiCNLqLnoaQ94KB/g2Ridc9NywQnmYF8hpCJcqtS382/dAe1+Dkm +W/BEsu9SnUfOqLXtxR6Ayw== +=N58I -----END PGP PUBLIC KEY BLOCK----- +pub 4096R/B3D8E1BA 2009-11-05 + Key fingerprint = 53C9 3582 1AA6 A755 BD33 7DB5 3595 395E B3D8 E1BA +uid Ralph Goers (CODE SIGNING KEY) +sig 3 B3D8E1BA 2009-11-05 Ralph Goers (CODE SIGNING KEY) +sub 4096R/2910DD22 2009-11-05 +sig B3D8E1BA 2009-11-05 Ralph Goers (CODE SIGNING KEY) -pub 1024D/0D811BBE 2006-11-14 - Key fingerprint = F3A0 4C59 5DB5 B6A5 F1EC A43E 3B7B BB10 0D81 1BBE -uid Yoav Shapira -sig 3 0D811BBE 2006-11-14 Yoav Shapira -sub 2048g/286BACF1 2006-11-14 -sig 0D811BBE 2006-11-14 Yoav Shapira +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG/MacGPG2 v2.0.12 (Darwin) + +mQINBErygmoBEADbs8zVUn5ZwbsG3tqT4x6U7SZYOtd3WXOtHjuu9Cyp74rZ19Pi +XNbYwIAoCgOI/nXVWwuOrNJH0pHaQ73slbNzLxo2ahQIkw9PbK4V3YXLai1r/W6T +xU94s7WECoiH8uuRAZFwbei87/xwwTVnfwQjKBThom05LbOebtIGHkSg4Xl3b+Me +5iqHYiw/QOujiKOqm05s1aTWtm45KB3/u80/5y+2+/vn9HXor61gibDkC/oclDuj +J1GYPCIAUvj95vw5n6Eq46I6aoed3BWCLD+qXBz3QJjwIKTYLOHO9iTCjPk1UmAq +NQhrENV7eeahFIDgL+b9wsm6CwuH36B7cdobsOltqBegpMczM+kwTbeaVwyI+S6Y +jQflqUclFctJCRxZYzUUL3C5X/yvb8Bj+WmoEjm3mSMEPUC+KwWeVGaXIrdw/yzX +Vziqu+PVWZYovNKsLGlL5zUJt3nV0xmDJdPuLRgheIfB2t4oqn0Ki/PzMLQhhX9+ +9zWc9WD9V8cIZtiSs1hRny5Ns33nQr0KkdGOj1lfVcZVrDv64VUSzofH2nGEWS+f +h9gkgD3aLHppt2XCH7tJK+wU/NlR5/0j+j3QwAfG5pziD0zMjvnKREfJ3aqqu9jj +8FgdJ5vJvo7hlq0zakD7qTUO0OJiELHcf8q0jfFdiqaocs4HZp1OO1w8hQARAQAB +tDJSYWxwaCBHb2VycyAoQ09ERSBTSUdOSU5HIEtFWSkgPHJnb2Vyc0BhcGFjaGUu +b3JnPokCNwQTAQoAIQUCSvKCagIbAwULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAK +CRA1lTles9jhunOxEACwm5J1+TvPfwDA/HTKQcXwm8vfyAgf7HkUVoi1BRcJpqWn +xa1KO3YIBj0luJkXw1D1LowLdH8/QHjjqxGliKqrKL+F7mDPlpuZ7mqj2JO+LUII +OXMD8PLqjJ0rqaZ9u7IuWAHcFHoy+wApkqCQSFIMUTQREyoBgQiu2lgf4vGB3pEN +O5Hsulky7BdWk/2v2ga1VdFBURh1Wykd4RLd6KLhonsnNe3CcParzzKTHG/JkTIT +4o7wZy0erv8UG4OBU3Db28Q4DiCCnwWb2LA0Az9eC7WRaIfA+Tx0x4PgtIhS20/3 +GZp9C1DsTsHnIYy5KLhx9hReqiky0Hnkt9puLVWyhPdbG2K+7KZH8CX1elTrCLDP +o25YwP1+xB9vmBoiKUwV60Ap5Jppup6k5CISfYzIE7wJ/pn7LXoE5m9H/rmWXQpq +f4GrNvMOaAiXnvYR8N2qeQeMwYtbm/hZTk7mlrf1xgJ5aHq13T/jaxIbFBdvh32Y +jPXNm53LcVf+H9uwy71dsmwCnnq6zxg83pBu2bpNb8d9MSg2MGT9yLdin3bvdnsy +9Kd4D08YcbdYyyby5FHpMFtqWSVvoCwsvztVE2bTC/ruR+AdZGl1+FxooqDhxeTF +V3Sxf9zA7mVKZgVEdULvmi1gT91YAVp+GBg/FY6pf264wneqzKrWmdxG4oM6fLkC +DQRK8oJqARAAzqD0AESdZa2wPgtiSQwRd+vn6YelEW52J3O9mP5HXVnQoVwJwikT +eUAHWXiEFhGCp6RAo6kv1Jx/hOOpdcF0oPmHcxb6X1kxhqnZgs3DDPaKFfALQb7V +Hr288GuIwVk09VY69gcFlWotidM5jSZ0N74rJmQJdbtaj9gyUz5+aW1YiuZ6IfFE +34j4psfvk3Db7RsQuGb7pmmFjQHXnBgcVo6h8N9un4P75hwer34sXDm9rutERzL1 +MZMEuG7FE8SYDO+x6+pvlCSowSgo+SinzAM4f+4AEfCaOUv/Hw/dhL4dYi75XMI4 +2B+mrD0+llfMKbMLofglRtxBA/oqgMkRAeg5LND+KoxqFBk6ztDrGjXIlf6TxPH5 +MY2pkizyYVQGt3GgSXnz/LuzwmIQfZDmHe15QE6r+I06AY1ViICoMz7NiPdgfVS9 +E3BlkPhs6OlsIgWE4pPnpuzuBo5CLQIHmMl+5IdJgFN+SNVV+4+stx4URMkaiUkc +p0Mm8oupuyB28VG/fOpOqg1VBjFrFutYMja86mRY3Bg7Xg64Jj7dqoFXKjvPUfjx +EuIamlEmNZM2n8pSsaPXPFAJG1H9y+yrVfa7L7ynAiqzWx8KrE3SnlKuEo/5ZVF3 +xR1vdsJ38BCY+DYlzixVDaPM7qCBzCVGxVDZ6rPsEfwgBTPAGP2BzW0AEQEAAYkC +HwQYAQoACQUCSvKCagIbDAAKCRA1lTles9jhulznD/oD95V8OrQuxY0+Af6DjLaZ +ENjUcOhYElu+WNT9neH2bu0JLiO8y3ZjY1mT0XBHZaBnNKfhjfjSlQRO0ipojQ2c +DQxnQ4gIkRn7Iz2wRcm6UJHOiCGR1w+DYAwVI/j33rrztg+yfpaET3s8k0wEOceW +j8lb7WII7ek7xhIZ/d0hNFwy92/UnuuKSmDfFClIwTzPShy3CB0oFQR3SMbhquaI +Z8+tOzYDDN9tQ00sO461VRgwmJ9fauieL/rLNRegigZrF0BYY4XusM1Bc2pXG/DV +flePMoNQTx9J+dqx9Wk5SjEQ0dZsFwpz5WrweWMpNBhZaBkjfWL7EsYNChaN7n7u +y8JgbO9FmRb4DPWvxk5otFqUv3fIPbt/X/XeFbV33eWp7kSDb9DL+YkXqBef4QLV +BOBGeIJhQgm0rTKtxFl+YLuiFM167F56IHTnv9bKEv3Un1puPGgWnCpnF6zBx5Xg +/3La4A01vkVydsb0P0Cx+ETPWCZzyRenut5dQLUAQEXz+G8HjdRf+aK824Mx4WAf +pV8zkCkVae+se/txEFxedb/Y5jfejMqFX4M07ZuAydoFkeyCMaxin7WZI4ZUW1+s +t7nSMQipZuv2XsTu6tbilQOccWm+5zILmBsSD7RT1+ek7F8ib130sFVsE4MKxXh0 +DGLPEPiyStLVF41310m6rA== +=LxkI +-----END PGP PUBLIC KEY BLOCK----- +pub 1024D/42196CA8 2009-05-05 +uid Christian Grobmeier (Apache Codesigning) +sig 3 42196CA8 2009-05-05 Christian Grobmeier (Apache Codesigning) +sig 3 460FEEAA 2009-05-06 [User-ID nicht gefunden] +sig P X 65D0FD58 2009-05-05 [User-ID nicht gefunden] +sub 2048g/427473DA 2009-05-05 +sig 42196CA8 2009-05-05 Christian Grobmeier (Apache Codesigning) -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.5 (MingW32) - -mQGiBEVZ4AwRBAC9WDbCjRX9Q81Con7cycGkkui6JZndLhX3Jbzlc/eHG0/fUetP -0c5ZdIvTyjj+L/DRI6btrgl+jR64qkuapsYD/KDXQGkpK5zPpmxUPmXJ5tfVTbOj -gacUm2cZjYjSK3dsIs4sDUqNYfBfdwesJ+Hycc7XqkTF1lO2MN9yp8g+4wCg0W8x -/ZYCTb9D8JOPzfSNf8cIFCkD/j5GXA2xlSXuAFBgWpFak5OkeF8cwEkv0CQ0zCqP -R/rTmDGO/73dpQEzgY+gLMSvtkK0pVEYaE15lg2mxma9d0pGE+fmsu5w7SQUip15 -HN5E3qP/VB4X1yp+YiHPGTDjRgJm+xbvTGSFFr0wNSSYCVpVGdYHNmetYsB5JqkH -YmiWA/4vnkWnkzQeUNNPvep0lSrEG9jiON4k/d5opWwjxIP4aev8V7//V9ASzznF -D6eEL23ePX5ZuKLyDeOSRAwaPpa/Rp4AkiUGzKK21wAwKip+lcbT5m2ButoQhgNI -ZlmnfhN7E2t2S6iS9VzHEo1S8Jv9uQZJ89Tp5fiFe1pXL2qBHrQhWW9hdiBTaGFw -aXJhIDx5b2F2c0Bjb21wdXRlci5vcmc+iGAEExECACAFAkVZ4AwCGwMGCwkIBwMC -BBUCCAMEFgIDAQIeAQIXgAAKCRA7e7sQDYEbvgiLAKDHEgeJyxlrxNJ4m51jOnhG -xlsLOQCbBWAdTjpMVcNqmd6Fa5fgyCbh8XS5Ag0ERVngFBAIAIEVU1iOoq4CyD3I -f+AChfSFAgqjKmjqEyPv2RDLPkI3g2FvC6HvOlUucIe6IjqvTXztdxSRQu2EGq5i -W8e5ajTZiI9ZNs26XLL4/q/gYRaDjUsI7J3PAOL9lNdws6ZoqlCh44R/cvekuixx -HoHGskGxAHBRdjv9Oqy4x5hR5kebGq9Ayf8CQZ3l7aRekwlMUyCsmMkNxmqMls2g -ViBFD0/9a/xodE2VMVMg5eQ8A0enlrGDghG9d2m586JtOje55rMVnVPkEuNkz9AC -DkR0CiwQqX72Ub10t/qcNqbDeMHFacOBYRKfS7Qdm3/jb8Tc4jO/AXFcUGbH5niz -pPGs+UMAAwUH/1M2unaFyfJddVPQRZCJEFxdlxkg40tewgjaNJLwnqOJXw1RENNM -bSx4Gvz8M6WvZtkvITt29P+O4EmGq+LYTKmLM/E399KuqoZGbyCu3Gm+RIxKmRkf -Y3izseOhrUX2ycUIOF1BFzIYs6HeO/sZeba1bapOFo/xS6NwnuJl6uXUmynGjVtY -gvQ+dLYAcDXUQJd+QjyXdsbnp1jmdSrqqscPGOquRAw7/sp/ivom4DDHMTz4HErz -NfHzn4z8kUE7T1EEpnFU4SBiJkpm/+yEhEq9hDG2GZmxfQd34iRXpC5B4ZbRiwW8 -p/bhzvcxZcrahQzu5yyq2+kGhK7IA9APFGSISQQYEQIACQUCRVngFAIbDAAKCRA7 -e7sQDYEbvppSAJ9+i7TzCNvZ4PK/odiIWeZ61+KKyACfSjQXnC5UbxndwtkOzFKf -Io8ZP0E= -=xT1M +Version: GnuPG v1.4.11 (Darwin) + +mQGiBEoAFh0RBACoIMutlZW5Isr0+btD/zsuxnCw5Ee2J+DANmA6Gvf4wiXPYw8X +evehIDiitZFCB/imcxF+1Qr+30c/+2V/j8TrDAqrj4UvQ8ryyejfR8aPT31C4lYF ++ktWT2PZA3ZOL03q8MtsLZiXdgRE5RwpUAGg2iAKlq4kx0RtDKJM3DHkQwCg9a7s +erb8gudgyDo7vjmATzu9d5cD/imS3/8CPWHnIfQMQNFkniShm0XoVCuZfQASf4I7 +ksRX+RfERc/RQ/vWoKW95DGupuBKm0KZYWjHgkd4NQcTvjtgVBpSksGuTg2dtY2R +96azS8Va0igUaUthZFCCD6TCHnOAsBCt47Fdv2ymlQiUZYXR1CPTkew/fXkBJJNw +mtH2A/4mT16lRfma4n5uBpjNMRD4juW4hI7/7/QS7xol4Zb74i9rcYldWY3U6AGt +lGUHeZ1ue9JZ+2SicJ25v+XAehbVsr+9NiiBqfOwGXij/d1UQTNsrsfvwYOC0foU +zw0xQFW5lYqJ7romLcly42jSC/lDkACDrL6MfeT5LWPId/cMKrQ/Q2hyaXN0aWFu +IEdyb2JtZWllciAoQXBhY2hlIENvZGVzaWduaW5nKSA8Z3JvYm1laWVyQGFwYWNo +ZS5vcmc+iGAEExECACAFAkoAFh0CGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAK +CRCG4CxaQhlsqK6wAKDLkpYfzS9kKqpEI9WAPYVW5prNLgCgmrZz7r8/bxUBloxL +yK+fUQzwGoiIRgQTEQIABgUCSgFPqwAKCRDB1SNHRg/uqvlqAJ0QyWCwmm4w8YGj +4gHoyThA8YbARgCcDayOVtHZh8fSLT4BGLMbtSSqYVmIawQQEQIAKwUCSgAajgWD +AeKFAB4aaHR0cDovL3d3dy5jYWNlcnQub3JnL2Nwcy5waHAACgkQ0rsNAWXQ/Vgc +RQCfbryBlBcu3GZR08g3YvAtOEWFvKkAmwdDHEZYUvfc1KlBF8ckDIMgqyTMuQIN +BEoAFh0QCADPnNYl1TZ5usGUhYd3L9mfgkP+gQTKQpdoR6B256Wk/D3gAgiHphdu +oOykZdPGarR7pdNYXlmpJyF9z4im9y3GtYoqzjg3k81IuiKC3XJo5pTBskysqMfk +r8/SvYTw3WkjnccxOy7/ZHTR95Kk4QE7v7ADuKM49vG6qqbrIjK5jQ8Xb9vuQjLr +2l2dlOcLnQB6+hyhPzGZpnt2OYMCmLFZyDXatJj3Rrh/Rmoz9jVyN2cVKk2Ho/+J +tjzbfwjjJaBBUlAsZPQBnk+raAn4IeNqSSCrOokq4h5IFi9BQdrk6sV1PPQ00zxo +RCUMA1YDmFmNSriqkpvrdsL3kVEUZct/AAMFCADNSCoj84hdKkXXO49G4Z2p0wX9 +mNfaQbAUZx3Y74ph4BXAZsjgikpbml0MeZnrWt7H4P5NBAzRPQ2ChxT8QhYfNRay +N102jNdnNkT3X3pfFrF/SDQq9lvqhjfYYz1vPY37tpdmW/IpOuER8b4EBw5V7HWe +IIlcDpHYZvOFv3yuJr1MyHwN1f50FAoJc9ZNxee1cKgAZkR1ZE66iTpjiTqdNmKZ +G8S6c1v6FLAB4ogFQmQ5WB7g2iQTDLj4k16suBFB9f3eSgtChg66dnOufYQgUCOT +ReT5+FfYU/x1E5YO+XRYR/HBP9SImvO9E8E/+HRGfqf2IzHTF5mDfGsA0rk0iEkE +GBECAAkFAkoAFh0CGwwACgkQhuAsWkIZbKjrlgCghD5yrAugimWHOYDtyKs53wcq +VgUAoL1bX0lIWF44l1wm2/d0FeLEU0Qx +=eW64 -----END PGP PUBLIC KEY BLOCK----- diff --git a/LICENSE b/LICENSE index d645695673..6279e5206d 100644 --- a/LICENSE +++ b/LICENSE @@ -187,7 +187,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 1999-2005 The Apache Software Foundation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/NOTICE b/NOTICE index 3f59805ce4..d697542317 100644 --- a/NOTICE +++ b/NOTICE @@ -1,2 +1,5 @@ -This product includes software developed by +Apache log4j +Copyright 2010 The Apache Software Foundation + +This product includes software developed at The Apache Software Foundation (http://www.apache.org/). diff --git a/NOTICE.txt b/NOTICE.txt deleted file mode 100644 index 8bb0be42be..0000000000 --- a/NOTICE.txt +++ /dev/null @@ -1,7 +0,0 @@ -This product includes software developed by -The Apache Software Foundation (http://www.apache.org/). - -This product includes source code based on Sun -Microsystems' book titled "Java Nativer Interface: -Programmer's Guide and Specification" and freely available -to the public at http://java.sun.com/docs/books/jni. diff --git a/NTEventLogAppender.amd64.dll b/NTEventLogAppender.amd64.dll new file mode 100644 index 0000000000..b2a8ee0daf Binary files /dev/null and b/NTEventLogAppender.amd64.dll differ diff --git a/build.properties.sample b/build.properties.sample index 39e8cefa4c..101a6c49eb 100644 --- a/build.properties.sample +++ b/build.properties.sample @@ -1,38 +1,58 @@ -# The xml api interface and a xml parser are required to build the -# JoranConfigurator. However, these are already available since Ant -# needs them too. Note also that these are required to run Chainsaw. -# They are commented out by default but may be commented in for -# customizations, e.g. when running Chainsaw from Ant version 1.4 -# or earlier. - -# xml.home=/java/jaxp-1.1 -# xml-api.jar=${xml.home}/xml-apis.jar -# xml-impl.jar=${xml.home}/xercesImpl.jar +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +# +# Providing a build.properties file is no longer +# necessary for an Ant build as long as one Maven build +# has previously been performed. +# + +# base location of support directories +# +lib.home.dir=/java +# The jaxp interface and a jaxp parser are required +# to build the DOMConfigurator. # -# by default assume that all necessary dependencies -# are relative to the user's home directory +# modern equivalent is xml-commons-apis.jar # -lib.home.dir=${user.home} +jaxp.home=${lib.home.dir}/crimson-1.1.3 +jaxp.jaxp.jar=${jaxp.home}/crimson.jar -# JavaMail API OPTIONAL; required to build the SMTPAppender +# JavaMail API Required to build the SMTPAppender javamail.jar=${lib.home.dir}/javamail-1.3.2/mail.jar + +# and JavaBeans Activation Framework +# http://java.sun.com/products/javabeans/jaf/index.jsp activation.jar=${lib.home.dir}/jaf-1.0.2/activation.jar -# JMS OPTIONAL; required to build the JMSAppender. + +# JMS interfaces are required to be on the classpath # in order to build the JMSAppender. -# API jar can be downloaded from http://java.sun.com/products/jms/docs.html jms.jar=${lib.home.dir}/jms1.1/lib/jms.jar # Required to build the org.apache.log4j.jmx package. jmx.home.dir=${lib.home.dir}/jmx-1_2_1-bin jmx.jar=${jmx.home.dir}/lib/jmxri.jar -jmx-extra.jar=${jmx.home.dir}/lib/jmxtools.jar - +jndi.jar=${lib.home.dir}/jndi-1_2_1/lib/jndi.jar -# Servlet api -servlet-api.jar=${lib.home.dir}/jakarta-tomcat-5.5.9/common/lib/servlet-api.jar +# Required to run Checkstyle. Available from http://checkstyle.sf.net +checkstyle.jar=${lib.home.dir}/checkstyle-2.2/checkstyle-all-2.2.jar # Velocity's Anakia task is used in the generation of the documentation # download from http://jakarta.apache.org @@ -42,57 +62,10 @@ velocity.jar=${lib.home.dir}/velocity-1.4/velocity-dep-1.4.jar # download for http://www.jdom.org/dist/binary/archive jdom.jar=${lib.home.dir}/jdom-b8/build/jdom.jar -# Describes the relative or full path to the Jakarta ORO Reg Exp jar file -# Required if you wish to use LogFilePatternReceiver or LikeRule (regexp) -jakarta-oro.jar=${lib.home.dir}/jakarta-oro-2.0.8/jakarta-oro-2.0.8.jar - - -# DBAppender/DBReceiver OPTIONAL: -# -# The org.apache.log4j.db package makes use of the -# javax.sql.DataSource interface which is included part of the JDBC -# standard extensions. These extensions ship with JDK 1.4 and later -# but not JDK 1.3 or 1.2. -# -# Download JDBC 2.0 Optional Package Binary from -# -# http://java.sun.com/products/jdbc/download.html#spec -# -#jdbc-stdext.jar=${lib.home.dir}/jdbc2_0-stdext.jar - -# --------------------------------------------------- -# JNDI API REQUIRED when building log4j with JDK 1.2) -# --------------------------------------------------- -# -# The JNDI API is required to build ContextJNDISelector, which has -# become a core log4j class. The JNDI API ships with JDK 1.3 and later, -# you do not need to load it separately. For JDK 1.2, you can get the -# JNDI API from -# -# http://java.sun.com/products/jndi/downloads/index.html - -#jndi.jar=/java/lib/jndi.jar - -# -# Jalopy source code reformatter -# -# -jalopy-ant.dir=${lib.home.dir}/jalopy-ant-0.6.2 - -# -# Checkstyle coding convention checker -# -checkstyle.jar=${lib.home.dir}/checkstyle-4.0-beta2/checkstyle-all-4.0-beta2.jar - # # CLIRR binary compatibility checker # http://clirr.sourceforge.net clirr-core.jar=${lib.home.dir}/clirr-0.6/clirr-core-0.6.jar # bcel 5.1 will throw NullPointerExceptions -bcel.jar=${lib.home.dir}/bcel-5.2rc1/bcel-5.2rc1.jar - -# -# JDIFF API change documentation generator -# http://jdiff.sourceforge.net -jdiff.home.dir=${lib.home.dir}/jdiff +bcel.jar=${lib.home.dir}/bcel-5.2/bcel-5.2.jar diff --git a/build.xml b/build.xml index 095ea0be25..2c6c97cd23 100644 --- a/build.xml +++ b/build.xml @@ -1,48 +1,70 @@ - - + + + + - + Building via Ant is not longer maintained. + This file will be removed as soon as the maven build is cleaned up. + +--> + + + + + - + + + - - - - - - - - + + + + + + - + + + + + + + + + + @@ -50,45 +72,24 @@ - - - - - - - - - - + - - - - - - - - - - - - - + + + + - - - - + @@ -105,32 +106,31 @@ + + + + + + + + - + + - + - - + - - - - - - - - - - + @@ -140,77 +140,34 @@ + These are the targets supported by this ANT build scpript: - build.core - compile core log4j classes. This target is dependent on JAXP, JNDI. - - build.jms - build classes dependent on the JMS API. - build.jmx - build classes dependent on the JMX API. - build.db - build classes dependent on JDBC API - build.nt - build classes specific to the Windows platform - build.smtp - build classes dependent on Java Mail API - build.xml - build classes in the org.apache.log4j.xml package - build - compile all project files - - log4j.jar - build the core log4j jar - log4j-'dep'.jar - where 'dep' is one of "optional", "jms", "jmx", "nt", "db", "smtp" and "xml". - jar - build all jar files - + build - compile all project files, if a certain library is missing, + then the compilation of its dependents are skipped. javadoc - build project javadoc files - dist - will create a complete distribution in dist - - + jar - build log4j-core and log4j jar files + + dist - will create a complete distribution in dist/ + Setting the env variable NO_JAVADOC will build the distribution + without running the javadoc target. + + release - will create a complete distribution in dist/ + using stricter settings for public distribution. - - + + - - - Could not find the JAXP API. - - Please set the jaxp-api.jar property in the build.properties file. - - - - - - - - - - The JNDI API is required to build ContextJNDISelector, which has - become a core log4j class. The JNDI API ships with JDK 1.3 and - later. For JDK 1.2, you can get the JNDI API from - - http://java.sun.com/products/jndi/downloads/index.html - - - - + + - - - - - - - - Missing org.apache.oro.* classes. - - Please make sure to that the "jakarta-oro.jar" property in build.properties - file is set correctly. - - - - - @@ -220,707 +177,374 @@ - + - - - Missing javax.management.* amd com.sun.jdmk.comm.HtmlAdaptorServer classes. - - Please make sure to that the "jmx.jar" and "jmx-extra.jar" properties in build.properties - file are set correctly. - - + + + + - + - + + + + - - - Missing javax.jms.* classes. - - Please make sure to that the "jms.jar" property in build.properties - file is set correctly. - - - - - - - - - - Missing java.mail.* classes. - - Please make sure that the "javamail.jar" and "activation.jar" - properties in the build.properties file are set correctly. - - - + + - - - - - - Missing javax.servlet.* classes. - - Please make sure that the "servlet-api.jar" property in build.properties - file is set correctly. - - + + + + + - - - - - - - + + + + + + - - Missing javax.sql.* classes. - - Please make sure to that the "jdbc-stdext.jar" property in build.properties - file is set correctly. - - + + + - + + + + + + + - - - - - - - - - - - - - - - - - Some jar files required to perform a full compile of log4j are not - available on the classpath. Update build.properties as needed. - - - - - - - - - - - - + - - - - - - - - - - - - - - - + + + debug="on"> - - + + + + + + - - - - - -
- - - -
-
- -
-
- - - - + + - + debug="on"> + + + + - + + + + + + - - - - -
- - - -
-
- -
- - - - + - - - - - - - - -
- - - -
-
- -
-
- - - - - - + classpath="${classpath}"> - - - - - - -
- - - -
-
- -
+
- - - - - + + includes="${stem}/net/SMTPAppender.java" + target="${javac.target}" + source="${javac.source}" + includeAntRuntime="${javac.includeAntRuntime}" + includeJavaRuntime="${javac.includeJavaRuntime}" + fork="${javac.fork}" + deprecation="${deprecation}"> - - - - - -
- - - -
-
- -
-
- - + + includes="${stem}/net/JMS*.java, ${stem}/or/jms/*.java" + target="${javac.target}" + source="${javac.source}" + includeAntRuntime="${javac.includeAntRuntime}" + includeJavaRuntime="${javac.includeJavaRuntime}" + fork="${javac.fork}" + deprecation="${deprecation}"> - - + + includes="${stem}/jmx/*.java" + excludes="${stem}/jmx/T.java" + target="${javac.target}" + source="${javac.source}" + includeAntRuntime="${javac.includeAntRuntime}" + includeJavaRuntime="${javac.includeJavaRuntime}" + fork="${javac.fork}" + deprecation="${deprecation}"> - - - - - -
- - - -
-
- -
-
- - - - - - - - - - - - -
- - - -
-
- -
-
- - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-
- -
-
- - + - - + - + + + + + + + - + - - - - - - - - - - -
- - - -
-
- -
+ + + + - - - - - - - - -
- - - -
-
- -
- -
- - - + + + + - - -Specify files to reformat with -Djalopy.files=PATTERN. - - - - - - - - - - - - + + + + + + + + + + + + + +
+ + + +
+
+ +
- - - - - - - - - + + + + + + + + + + + +
+ + + +
+
+ +
- + + - - + + - - - - - - - + header='<b>Log4j ${version}</b><!-- Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the 'License'); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an 'AS IS' BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +-->' + bottom="Copyright 2000-2007 Apache Software Foundation."> + - - - - - - - + + - - + - - + + - + @@ -930,161 +554,201 @@ Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Ap - + - - + - -Dclirr-core.jar=PATH must be specified. - -Dbcel.jar=PATH must be specified. - -Dreference.jar=PATH must be specified. + + + + clirr-core-${clirr.version}.jar not in maven repo. Run mvn clirr:check to download. + + + + bcel-${bcel.version}.jar not in maven repo. Run mvn clirr:check to download. + + + + log4j-${reference.version}.jar not in maven repo. Run mvn clirr:check to download. - - - - + + + + + - - - - - - - - - - - - - - - - + + + + - - - + + + - - + - + - - - - - - - - - AnakiaTask is not present! Please check to make sure that - the velocity.jar property is specified and contains the correct path. - + + + + - - - - - - - - - - - - - - + - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - + - - - - - + + + + - - + + + + - - + + + includes="apache-log4j-${version}/**" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1119,7 +783,7 @@ Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Ap - + @@ -1142,7 +806,6 @@ Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Ap -
diff --git a/contribs/CONTENTS b/contribs/CONTENTS new file mode 100644 index 0000000000..a1125d40e2 --- /dev/null +++ b/contribs/CONTENTS @@ -0,0 +1,116 @@ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +---------------------------------------------------------------------- +WARNING: The contents of the contribs/ directory is not guaranteed to +work properly. Some files might not even compile. +---------------------------------------------------------------------- + +Each directory corresponds to the name of an author containing his/her +contributions. + + +EirikLygre/ +========== + + DailyFileAppender1.java + + DailyFileAppender extends FileAppender to use filenames formatted with + date/time information. The filename is recomputed every day at midnight. + Note that the filename doesn't have to change every day, making it possible + to have logfiles which are per-week or per-month. + +JamesHouse/ +========== + + LogTextPanel.java + LogTextPanelExample.java + TextPanelAppender.java + +JimMoore/ +======== + + LoggingOutputStream.java + + Allows the user to divert System.out and System.err to log4j. + + WARNING: Be sure to read the included e-mails to understand the dangers of + WARNING: redirecting the console to LoggingOutputStream. + + +LeosLiterak/ +=========== + + TempFileAppender.java + + TempFileAppender creates new unique file for each logging statement. + +MarkDouglas/ +=========== + + SocketNode2.java + SocketServer2.java + + Small changes to SocketServer and SockerNode to allow the client machine name + to be displayed in the logging output. This is important for us as we are + using a single logging server with several clients. + +KevinSteppe/ +=========== + + JDBCAppender.java + JDBCTest.java + + +KitchingSimon/ +============= + + DatagramStringAppender.java + DatagramStringWriter.java + logconfig.xml + SingleLineTracerPrintWriter.java + udpserver.pl + + A set of files that implement an Appender which sends messages to a + remote host/port via UDP (datagram). Message formatting is + performed at the at the client end, mainly so that: + (a) the UDP server application does not have to be in java + (b) non-java clients can send messages to the same UDP server. + +ThomasFenner/ +============ + + Yet one more JDBCAppender. + + JDBCAppender.java + JDBCConnectionHandler.java + JDBCIDHandler.java + JDBCLogger.java + Log4JTest.java + code_example1.java + code_example2.java + configfile_example.txt + +Volker Mentzner/ +=============== + + HTTPRequestHandler.java + Log4jRequestHandler.java + PluggableHTTPServer.java + RootRequestHandler.java + UserDialogRequestHandler.java + + Allows users to configure log4j at runtime using a web-browser. \ No newline at end of file diff --git a/contribs/CekiGulcu/AppenderTable.java b/contribs/CekiGulcu/AppenderTable.java new file mode 100644 index 0000000000..fbb18f5aee --- /dev/null +++ b/contribs/CekiGulcu/AppenderTable.java @@ -0,0 +1,245 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import org.apache.log4j.helpers.CyclicBuffer; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.log4j.Layout; +import org.apache.log4j.PatternLayout; +import org.apache.log4j.spi.LoggingEvent; + +import javax.swing.JFrame; +import javax.swing.JButton; +import javax.swing.JTable; +import javax.swing.JTextArea; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableCellRenderer; +import javax.swing.JScrollPane; +import javax.swing.BoxLayout; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; +import java.awt.Container; + +/** + The AppenderTable illustrates one possible implementation of + an Table possibly containing a great many number of rows. + +

In this particular example we use a fixed size buffer + (CyclicBuffer) although this data structure could be easily + replaced by dynamically growing one, such as a Vector. The required + properties of the data structure is 1) support for indexed element + access 2) support for the insertion of new elements at the end. + +

Experimentation on my 1400Mhz AMD machine show that it takes + about 45 micro-seconds to insert an element in the table. This + number does not depend on the size of the buffer. It takes as much + (or as little) time to insert one million elements to a buffer of + size 10 as to a buffer of size 10'000. It takes about 4 seconds to + insert a total of 100'000 elements into the table. + +

On windows NT the test will run about twice as fast if you give + the focus to the window that runs "java AppenderTable" and not the + window that contains the Swing JFrame. */ +public class AppenderTable extends JTable { + + + static Logger logger = Logger.getLogger(AppenderTable.class); + + static public void main(String[] args) { + + if(args.length != 2) { + System.err.println( + "Usage: java AppenderTable bufferSize runLength\n" + +" where bufferSize is the size of the cyclic buffer in the TableModel\n" + +" and runLength is the total number of elements to add to the table in\n" + +" this test run."); + return; + } + + JFrame frame = new JFrame("JTableAppennder test"); + Container container = frame.getContentPane(); + + AppenderTable tableAppender = new AppenderTable(); + + int bufferSize = Integer.parseInt(args[0]); + AppenderTableModel model = new AppenderTableModel(bufferSize); + tableAppender.setModel(model); + + int runLength = Integer.parseInt(args[1]); + + JScrollPane sp = new JScrollPane(tableAppender); + sp.setPreferredSize(new Dimension(250, 80)); + + container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS)); + container.add(sp); + + // The "ADD" button is intended for manual testing. It will + // add one new logging event to the table. + JButton button = new JButton("ADD"); + container.add(button); + button.addActionListener(new JTableAddAction(tableAppender)); + + frame.setSize(new Dimension(500,300)); + frame.setVisible(true); + + long before = System.currentTimeMillis(); + + int i = 0; + while(i++ < runLength) { + LoggingEvent event = new LoggingEvent("x", logger, Level.ERROR, + "Message "+i, null); + tableAppender.doAppend(event); + } + + long after = System.currentTimeMillis(); + + long totalTime = (after-before); + + System.out.println("Total time :"+totalTime+ " milliseconds for "+ + "runLength insertions."); + System.out.println("Average time per insertion :" + +(totalTime*1000/runLength)+ " micro-seconds."); + + + } + + public + AppenderTable() { + this.setDefaultRenderer(Object.class, new Renderer()); + } + + /** + When asked to append we just insert directly into the model. In a + real appender we would use two buffers one for accumulating + events and another to accumalte events but after filtering. Only + the second buffer would be displayed in the table and made + visible to the user.*/ + public + void doAppend(LoggingEvent event) { + ((AppenderTableModel)getModel()).insert(event); + } + + /** + The Renderer is required to display object in a friendlier from. + This particular renderer is just a JTextArea. + +

The important point to note is that we only need *one* + renderer. */ + class Renderer extends JTextArea implements TableCellRenderer { + + PatternLayout layout; + + public + Renderer() { + layout = new PatternLayout("%r %p %c [%t] - %m"); + } + + public Component getTableCellRendererComponent(JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column) { + + // If its a LoggingEvent than format it using our layout. + if(value instanceof LoggingEvent) { + LoggingEvent event = (LoggingEvent) value; + String str = layout.format(event); + setText(str); + } else { + setText(value.toString()); + } + return this; + } + } +} + +class AppenderTableModel extends AbstractTableModel { + + CyclicBuffer cb; + + AppenderTableModel(int size) { + cb = new CyclicBuffer(size); + } + + /** + Insertion to the model always results in a fireTableDataChanged + method call. Suprisingly enough this has no crippling impact on + performance. */ + public + void insert(LoggingEvent event) { + cb.add(event); + fireTableDataChanged(); + } + + /** + We assume only one column. + */ + public + int getColumnCount() { + return 1; + } + + /** + The row count is given by the number of elements in the + buffer. This number is guaranteed to be between 0 and the buffer + size (inclusive). */ + public int getRowCount() { + return cb.length(); + } + + /** + Get the value in a given row and column. We suppose that there is + only one colemn so we are only concerned with the row. + +

Interesting enough this method returns an object. This leaves + the door open for a TableCellRenderer to render the object in + a variety of ways. + */ + public + Object getValueAt(int row, int col) { + return cb.get(row); + } +} + + +/** + The JTableAddAction is called when the user clicks on the "ADD" + button. +*/ +class JTableAddAction implements ActionListener { + + AppenderTable appenderTable; + Logger dummy = Logger.getLogger("x"); + int counter = 0; + public + JTableAddAction(AppenderTable appenderTable) { + this.appenderTable = appenderTable; + } + + public + void actionPerformed(ActionEvent e) { + counter++; + LoggingEvent event = new LoggingEvent("x", dummy, Level.DEBUG, + "Message "+counter, null); + appenderTable.doAppend(event); + } +} diff --git a/contribs/CekiGulcu/Transform.java b/contribs/CekiGulcu/Transform.java new file mode 100644 index 0000000000..dcd9c15396 --- /dev/null +++ b/contribs/CekiGulcu/Transform.java @@ -0,0 +1,219 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.xml; + +import org.apache.log4j.Category; +import org.apache.log4j.Layout; +import org.apache.log4j.PropertyConfigurator; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.helpers.OptionConverter; +import org.apache.log4j.helpers.DateLayout; + +import org.xml.sax.ContentHandler; +import org.xml.sax.Locator; +import org.xml.sax.Attributes; +import org.xml.sax.XMLReader; +import org.xml.sax.ext.LexicalHandler; +import org.xml.sax.helpers.XMLReaderFactory; +import org.xml.sax.SAXException; +import org.apache.xerces.parsers.SAXParser; + +import org.apache.trax.Processor; +import org.apache.trax.TemplatesBuilder; +import org.apache.trax.Templates; +import org.apache.trax.Transformer; +import org.apache.trax.Result; +import org.apache.trax.ProcessorException; +import org.apache.trax.ProcessorFactoryException; +import org.apache.trax.TransformException; + + +import org.apache.serialize.SerializerFactory; +import org.apache.serialize.Serializer; +import org.apache.serialize.OutputFormat; +import org.xml.sax.helpers.AttributesImpl; + + +import java.io.FileOutputStream; +import java.io.IOException; + + +public class Transform { + + public static void main(String[] args) throws Exception { + PropertyConfigurator.disableAll(); + PropertyConfigurator.configure("x.lcf"); + + // I. Instantiate a stylesheet processor. + Processor processor = Processor.newInstance("xslt"); + + // II. Process the stylesheet. producing a Templates object. + + // Get the XMLReader. + XMLReader reader = XMLReaderFactory.createXMLReader(); + + // Set the ContentHandler. + TemplatesBuilder templatesBuilder = processor.getTemplatesBuilder(); + reader.setContentHandler(templatesBuilder); + + // Set the ContentHandler to also function as a LexicalHandler, which + // includes "lexical" (e.g., comments and CDATA) events. The Xalan + // TemplatesBuilder -- org.apache.xalan.processor.StylesheetHandler -- is + // also a LexicalHandler). + if(templatesBuilder instanceof LexicalHandler) { + reader.setProperty("http://xml.org/sax/properties/lexical-handler", + templatesBuilder); + } + + // Parse the stylesheet. + reader.parse(args[0]); + + //Get the Templates object from the ContentHandler. + Templates templates = templatesBuilder.getTemplates(); + + // III. Use the Templates object to instantiate a Transformer. + Transformer transformer = templates.newTransformer(); + + // IV. Perform the transformation. + + // Set up the ContentHandler for the output. + FileOutputStream fos = new FileOutputStream(args[2]); + Result result = new Result(fos); + Serializer serializer = SerializerFactory.getSerializer("xml"); + serializer.setOutputStream(fos); + + transformer.setContentHandler(serializer.asContentHandler()); + + // Set up the ContentHandler for the input. + org.xml.sax.ContentHandler chandler = transformer.getInputContentHandler(); + DC dc = new DC(chandler); + reader.setContentHandler(dc); + if(chandler instanceof LexicalHandler) { + reader.setProperty("http://xml.org/sax/properties/lexical-handler", + chandler); + } else { + reader.setProperty("http://xml.org/sax/properties/lexical-handler", + null); + } + + // Parse the XML input document. The input ContentHandler and + // output ContentHandler work in separate threads to optimize + // performance. + reader.parse(args[1]); + } +} + + class DC implements ContentHandler { + + static Category cat = Category.getInstance("DC"); + + ContentHandler chandler; + + DC(ContentHandler chandler) { + this.chandler = chandler; + } + + + public + void characters(char[] ch, int start, int length) + throws org.xml.sax.SAXException { + cat.debug("characters: ["+new String(ch, start, length)+ "] called"); + chandler.characters(ch, start, length); + + } + + public + void endDocument() throws org.xml.sax.SAXException { + cat.debug("endDocument called."); + chandler.endDocument(); + + } + + public + void endElement(String namespaceURI, String localName, String qName) + throws org.xml.sax.SAXException { + cat.debug("endElement("+namespaceURI+", "+localName+", "+qName+") called"); + chandler.endElement(namespaceURI, localName, qName); + } + + public + void endPrefixMapping(String prefix) throws org.xml.sax.SAXException { + cat.debug("endPrefixMapping("+prefix+") called"); + chandler.endPrefixMapping(prefix); + } + + public + void ignorableWhitespace(char[] ch, int start, int length) + throws org.xml.sax.SAXException { + cat.debug("ignorableWhitespace called"); + chandler.ignorableWhitespace(ch, start, length); + } + + public + void processingInstruction(java.lang.String target, java.lang.String data) + throws org.xml.sax.SAXException { + cat.debug("processingInstruction called"); + chandler.processingInstruction(target, data); + } + + public + void setDocumentLocator(Locator locator) { + cat.debug("setDocumentLocator called"); + chandler.setDocumentLocator(locator); + } + + public + void skippedEntity(String name) throws org.xml.sax.SAXException { + cat.debug("skippedEntity("+name+") called"); + chandler.skippedEntity(name); + } + + public + void startDocument() throws org.xml.sax.SAXException { + cat.debug("startDocument called"); + chandler.startDocument(); + } + + public + void startElement(String namespaceURI, String localName, String qName, + Attributes atts) throws org.xml.sax.SAXException { + cat.debug("startElement("+namespaceURI+", "+localName+", "+qName+")called"); + + if("log4j:event".equals(qName)) { + cat.debug("-------------"); + if(atts instanceof org.xml.sax.helpers.AttributesImpl) { + AttributesImpl ai = (AttributesImpl) atts; + int i = atts.getIndex("timestamp"); + ai.setValue(i, "hello"); + } + String ts = atts.getValue("timestamp"); + cat.debug("New timestamp is " + ts); + } + chandler.startElement(namespaceURI, localName, qName, atts); + } + + public + void startPrefixMapping(String prefix, String uri) + throws org.xml.sax.SAXException { + cat.debug("startPrefixMapping("+prefix+", "+uri+") called"); + chandler.startPrefixMapping(prefix, uri); + } + + +} + diff --git a/contribs/EirikLygre/DailyFileAppender1.java b/contribs/EirikLygre/DailyFileAppender1.java new file mode 100644 index 0000000000..eb0a3d216c --- /dev/null +++ b/contribs/EirikLygre/DailyFileAppender1.java @@ -0,0 +1,242 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +package org.apache.log4j; + +import java.io.IOException; +import java.io.Writer; +import java.io.FileWriter; +import java.io.File; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.text.SimpleDateFormat; +import java.util.Date; +import org.apache.log4j.helpers.OptionConverter; +import org.apache.log4j.helpers.QuietWriter; +import org.apache.log4j.helpers.CountingQuietWriter; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.spi.ErrorCode; + +/** + DailyFileAppender extends FileAppender to use filenames formatted with + date/time information. The filename is recomputed every day at midnight. + Note that the filename doesn't have to change every day, making it possible + to have logfiles which are per-week or per-month. + + The appender computes the proper filename using the formats specified in + + java.text.SimpleDateFormat. The format requires that most static text is + enclosed in single quotes, which are removed. The examples below show how + quotes are used to embed static information in the format. + + Sample filenames: + + + Filename pattern Filename + "'/logs/trace-'yyyy-MM-dd'.log'" /logs/trace-2000-12-31.log + "'/logs/trace-'yyyy-ww'.log'" /logs/trace-2000-52.log + + + @author Eirik Lygre +*/ +public class DailyFileAppender extends FileAppender { + + /** + A string constant used in naming the option for setting the + filename pattern. Current value of this string constant is + FileNamePattern. + */ + static final public String FILE_NAME_PATTERN_OPTION = "FilePattern"; + + /** + The filename pattern + */ + private String fileNamePattern = null; + + /** + The actual formatted filename that is currently being written to + */ + private String currentFileName = null; + + /** + The timestamp when we shall next recompute the filename + */ + private long nextFilenameComputingMillis = System.currentTimeMillis () - 1; + + /** + The default constructor does no longer set a default layout nor a + default output target. */ + public + DailyFileAppender() { + } + + /** + Instantiate a RollingFileAppender and open the file designated by + filename. The opened filename will become the ouput + destination for this appender. + +

If the append parameter is true, the file will be + appended to. Otherwise, the file desginated by + filename will be truncated before being opened. + */ + public DailyFileAppender (Layout layout,String filename,boolean append) throws IOException { + super(layout, filename, append); + } + + /** + Instantiate a FileAppender and open the file designated by + filename. The opened filename will become the output + destination for this appender. + +

The file will be appended to. */ + public DailyFileAppender (Layout layout,String filename) throws IOException { + super(layout, filename); + } + + /** + Set the current output file. + + The function will compute a new filename, and open a new file only + when the name has changed. + + The function is automatically called once a day, to allow for + daily files -- the purpose of this class. + */ + + public + synchronized + void setFile(String fileName, boolean append) throws IOException { + + /* Compute filename, but only if fileNamePattern is specified */ + if (fileNamePattern == null) { + errorHandler.error("Missing file pattern (" + FILE_NAME_PATTERN_OPTION + ") in setFile()."); + return; + } + + Date now = new Date(); + + fileName = new SimpleDateFormat(fileNamePattern).format (now); + if (fileName.equals(currentFileName)) + return; + + /* Set up next filename checkpoint */ + DailyFileAppenderCalendar c = new DailyFileAppenderCalendar(); + c.rollToNextDay (); + nextFilenameComputingMillis = c.getTimeInMillis (); + + currentFileName = fileName; + + super.setFile(fileName, append); + } + + /** + This method differentiates RollingFileAppender from its super + class. + + */ + protected + void subAppend(LoggingEvent event) { + + if (System.currentTimeMillis () >= nextFilenameComputingMillis) { + try { + setFile (super.fileName, super.fileAppend); + } + catch(IOException e) { + System.err.println("setFile(null, false) call failed."); + e.printStackTrace(); + } + } + + super.subAppend(event); + } + + /** + Retuns the option names for this component, namely {@link + #FILE_NAME_PATTERN_OPTION} in + addition to the options of {@link FileAppender#getOptionStrings + FileAppender}. + */ + public + String[] getOptionStrings() { + + return OptionConverter.concatanateArrays(super.getOptionStrings(), + new String[] {FILE_NAME_PATTERN_OPTION}); + } + + /** + Set the options for the appender + */ + public + void setOption(String key, String value) { + super.setOption(key, value); + if(key.equalsIgnoreCase(FILE_NAME_PATTERN_OPTION)) { + fileNamePattern = value; + } + } + + /** + If the a value for {@link #FILE_OPTION} is non-null, then {@link + #setFile} is called with the values of {@link #FILE_OPTION} and + {@link #APPEND_OPTION}. + + @since 0.8.1 */ + public + void activateOptions() { + try { + setFile(null, super.fileAppend); + } + catch(java.io.IOException e) { + errorHandler.error("setFile(null,"+fileAppend+") call failed.", + e, ErrorCode.FILE_OPEN_FAILURE); + } + } +} + +/** + DailyFileAppenderCalendar is a helper class to DailyFileAppender. Using + this class, it is easy to compute and access the next Millis() + + It subclasses the standard + + java.util.GregorianCalendar-object, to allow access to the protected + function getTimeInMillis(), which it then exports. + + @author Eirik Lygre +*/ +class DailyFileAppenderCalendar extends java.util.GregorianCalendar +{ + /** + Returns the current time in Millis + */ + public long getTimeInMillis() { + return super.getTimeInMillis(); + } + + /** + Roll the date to the next hour, with minute, second and millisecond + set to zero. + */ + public void rollToNextDay () { + this.add(java.util.Calendar.DATE, 0); + this.add(java.util.Calendar.HOUR, 0); + this.set(java.util.Calendar.MINUTE, 0); + this.set(java.util.Calendar.SECOND, 0); + this.set(java.util.Calendar.MILLISECOND, 0); + } +} \ No newline at end of file diff --git a/contribs/EirikLygre/mail-2001-01-18 b/contribs/EirikLygre/mail-2001-01-18 new file mode 100644 index 0000000000..e1b168ea83 --- /dev/null +++ b/contribs/EirikLygre/mail-2001-01-18 @@ -0,0 +1,44 @@ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +Delivered-To: urba-cgu@urbanet.ch +To: Ceki Gulcu +From: Eirik_Lygre/evita/no%EVITA@evita.no +Subject: Re: Suggestion for new appender "DailyFileAppender" +Date: Thu, 18 Jan 2001 20:18:27 +0100 +X-MIMETrack: Serialize by Router on domino1/evita/no(Release 5.0.5 |September 22, 2000) at + 18.01.2001 20:18:30 + + + +This version subclasses GregorianCalendar, to get access to the +millis-variable used in the Calendar-classes (it is protected). + + +What do you think? + + +Eirik + + +++++++++++ +Eirik Lygre +eirik.lygre@evita.no +e-vita as, Stortorvet 3, Oslo +Mobil: (+47) 905 66476 +Fax: (+47) 23 35 70 51 + DailyFileAppender1.jav \ No newline at end of file diff --git a/contribs/JamesHouse/LogTextPanel.java b/contribs/JamesHouse/LogTextPanel.java new file mode 100644 index 0000000000..56b989aede --- /dev/null +++ b/contribs/JamesHouse/LogTextPanel.java @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.gui; + +import java.awt.Color; +import java.awt.Image; +import java.awt.Toolkit; +import java.awt.BorderLayout; + +import javax.swing.*; +import javax.swing.text.StyledDocument; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.StyleConstants; + +import java.util.Hashtable; +import java.util.StringTokenizer; +import java.util.Enumeration; +import java.util.ArrayList; + +import org.apache.log4j.*; + +public class LogTextPanel extends JPanel { + + private JScrollBar scrollBar; + private JTextPane textPane; + private JCheckBox cbxTail; + private StyledDocument doc; + + private Hashtable fontAttributes; + + private int eventBufferMaxSize = 10000; + private ArrayList eventBuffer = new ArrayList(eventBufferMaxSize); + private int eventViewIndex = 0; + + public LogTextPanel() { + constructComponents(); + createDefaultFontAttributes(); + } + + private void constructComponents() { + // setup the panel's additional components... + this.setLayout(new BorderLayout()); + + cbxTail = new JCheckBox(); + cbxTail.setSelected(true); + cbxTail.setText("Tail log events"); + + JPanel bottomPanel = new JPanel(); + bottomPanel.add(cbxTail, null); + + textPane = new JTextPane(); + textPane.setEditable(false); + textPane.setText(""); + doc = textPane.getStyledDocument(); + + scrollBar = new JScrollBar(JScrollBar.VERTICAL); + + this.add(bottomPanel, BorderLayout.SOUTH); + this.add(scrollBar, BorderLayout.EAST); + this.add(textPane, BorderLayout.CENTER); + } + + public + void setTextBackground(Color color) { + textPane.setBackground(color); + } + + public + void setTextBackground(String v) { + textPane.setBackground(parseColor(v)); + } + + private void createDefaultFontAttributes() { + Priority[] prio = Priority.getAllPossiblePriorities(); + + fontAttributes = new Hashtable(); + for (int i=0; i= eventBufferMaxSize) { + for(int i=0; i < evts.length; i++) { + eventBuffer.remove(0); + } + eventViewIndex -= evts.length; + if(eventViewIndex < 0) + eventViewIndex = 0; + } + for(int i=0; i < evts.length; i++) + eventBuffer.add(evts[i]); + + if((eventBuffer.size() > maxR) && cbxTail.isSelected()) { + eventViewIndex = (eventBuffer.size() - maxR); + } + + // only redraw if new line is visible... + if((maxR < 0) || (eventBuffer.size() >= eventViewIndex && eventBuffer.size() <= (eventViewIndex + maxR))) + drawText(); + } + + int maxR = -1; + + void drawText() { + if(maxR < 0) + maxR = textPane.getHeight() / textPane.getFontMetrics(textPane.getFont()).getHeight(); + try { + doc.remove(0, doc.getLength()); + } catch(Exception e) { e.printStackTrace(); } + + for(int i=eventViewIndex; (i < eventBuffer.size()) && (i < (eventViewIndex + maxR)); i++) { + EventBufferElement evt = (EventBufferElement)eventBuffer.get(i); + + try { + doc.insertString(doc.getLength(), evt.text, (MutableAttributeSet)fontAttributes.get(evt.prio)); + } catch(Exception e) { e.printStackTrace(); } + } + } + + +} \ No newline at end of file diff --git a/contribs/JamesHouse/LogTextPanelExample.java b/contribs/JamesHouse/LogTextPanelExample.java new file mode 100644 index 0000000000..c8898eec32 --- /dev/null +++ b/contribs/JamesHouse/LogTextPanelExample.java @@ -0,0 +1,132 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.gui.examples; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; + +import org.apache.log4j.*; +import org.apache.log4j.gui.TextPanelAppender; + +public class LogTextPanelExample { + boolean packFrame = false; + + String catName = "dum.cat.name"; + + public LogTextPanelExample() { + + // setup the logging + TextPanelAppender tpa = new TextPanelAppender(new PatternLayout("%-5p %d [%t]: %m%n"), "logTextPanel"); + tpa.setThreshold(Priority.DEBUG); + Category cat = Category.getInstance(catName); + cat.addAppender(tpa); + + LogFrame frame = new LogFrame(tpa); + frame.validate(); + + //Center the frame (window), and show it + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Dimension frameSize = frame.getSize(); + if (frameSize.height > screenSize.height) { + frameSize.height = screenSize.height; + } + if (frameSize.width > screenSize.width) { + frameSize.width = screenSize.width; + } + frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2); + frame.setVisible(true); + } + + /**Main method*/ + public static void main(String[] args) { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } + catch(Exception e) { + e.printStackTrace(); + } + LogTextPanelExample foo = new LogTextPanelExample(); + new LogTextPanelExampleGenThread(foo.catName); + } +} + +class LogFrame extends JFrame { + + public LogFrame(TextPanelAppender tpa) { + enableEvents(AWTEvent.WINDOW_EVENT_MASK); + JPanel contentPane = (JPanel) this.getContentPane(); + contentPane.setLayout(new BorderLayout()); + this.setSize(new Dimension(600, 400)); + this.setTitle("LogTextPanel Example"); + contentPane.add(tpa.getLogTextPanel(), BorderLayout.CENTER); + } + + // exit when window is closed + protected void processWindowEvent(WindowEvent e) { + super.processWindowEvent(e); + if (e.getID() == WindowEvent.WINDOW_CLOSING) { + System.exit(0); + } + } +} + +class LogTextPanelExampleGenThread extends Thread { + + String catName; + + public LogTextPanelExampleGenThread(String catName) { + this.catName = catName; + this.setPriority(Thread.NORM_PRIORITY - 1); + this.start(); + } + + public void run() { + Category cat = Category.getInstance(catName); + int cnt = 0; + while(true) { + cnt++; + int randEvt = (int)(Math.random() * 125); + if(randEvt < 3) + cat.fatal("{" + cnt + "} Something screwed up bad."); + else if(randEvt < 10) + cat.error("{" + cnt + "} An error occured while trying to delete all of your files."); + else if(randEvt < 25) + cat.warn("{" + cnt + "} It seems as if your hard disk is getting full."); + else if(randEvt < 55) + cat.info("{" + cnt + "} It is now time for tea."); + else if(randEvt < 65) + cat.debug("{" + cnt + "} Something bad is happening on line 565 of com.foo.Crap"); + else if(randEvt < 75) + cat.debug("{" + cnt + "} Input value for xe343dd is not equal to xe39dfd!"); + else if(randEvt < 85) + cat.debug("{" + cnt + "} Successfully reached line 2312 of com.foo.Goo"); + else if(randEvt < 105) + cat.debug("{" + cnt + "} Here is some extra handy debugging information for you."); + else if(randEvt < 115) + cat.debug("{" + cnt + "} The file you are about to write to is not open."); + else if(randEvt < 125) + cat.debug("{" + cnt + "} The input value to the method was ."); + + try { + Thread.sleep(10); + } + catch(Exception e) {} + + } + } +} \ No newline at end of file diff --git a/contribs/JamesHouse/TextPanelAppender.java b/contribs/JamesHouse/TextPanelAppender.java new file mode 100644 index 0000000000..bb46064935 --- /dev/null +++ b/contribs/JamesHouse/TextPanelAppender.java @@ -0,0 +1,217 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.gui; + + +import java.awt.Color; +import java.awt.Image; +import java.awt.Toolkit; +import java.io.*; +import java.net.URL; +import java.util.Enumeration; +import java.util.StringTokenizer; +import java.util.Hashtable; +import java.util.ArrayList; + +import javax.swing.JPanel; + +import org.apache.log4j.*; + +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.helpers.Loader; +import org.apache.log4j.helpers.QuietWriter; +import org.apache.log4j.helpers.TracerPrintWriter; +import org.apache.log4j.helpers.OptionConverter; + + +/** + * + * @author James House + */ + +public class TextPanelAppender extends AppenderSkeleton { + + TracerPrintWriter tp; + StringWriter sw; + QuietWriter qw; + LogTextPanel logTextPanel; + LogPublishingThread logPublisher; + + final String COLOR_OPTION_FATAL = "Color.Fatal"; + final String COLOR_OPTION_ERROR = "Color.Error"; + final String COLOR_OPTION_WARN = "Color.Warn"; + final String COLOR_OPTION_INFO = "Color.Info"; + final String COLOR_OPTION_DEBUG = "Color.Debug"; + final String COLOR_OPTION_BACKGROUND = "Color.Background"; + final String FONT_NAME_OPTION = "Font.Name"; + final String FONT_SIZE_OPTION = "Font.Size"; + final String EVENT_BUFFER_SIZE_OPTION = "EventBuffer.Size"; + + public TextPanelAppender(Layout layout, String name) { + this.layout = layout; + this.name = name; + this.sw = new StringWriter(); + this.qw = new QuietWriter(sw, errorHandler); + this.tp = new TracerPrintWriter(qw); + setLogTextPanel(new LogTextPanel()); + logPublisher = new LogPublishingThread(logTextPanel, Priority.ERROR, 500); + //logPublisher = new LogPublishingThread(logTextPanel, null, 500); + } + + public + void close() { + } + + public void append(LoggingEvent event) { + + String text = this.layout.format(event); + + // Print Stacktrace + // Quick Hack maybe there is a better/faster way? + if (event.throwable!=null) { + event.throwable.printStackTrace(tp); + for (int i=0; i< sw.getBuffer().length(); i++) { + if (sw.getBuffer().charAt(i)=='\t') + sw.getBuffer().replace(i,i+1," "); + } + text += sw.toString(); + sw.getBuffer().delete(0,sw.getBuffer().length()); + } + else + if(!text.endsWith("\n")) + text += "\n"; + + logPublisher.publishEvent(event.priority, text); + } + + public + JPanel getLogTextPanel() { + return logTextPanel; + } + + public + String[] getOptionStrings() { + return new String[] { COLOR_OPTION_FATAL, COLOR_OPTION_ERROR, + COLOR_OPTION_WARN, COLOR_OPTION_INFO, COLOR_OPTION_DEBUG, + COLOR_OPTION_BACKGROUND, FONT_NAME_OPTION, FONT_SIZE_OPTION}; + } + + + public + void setName(String name) { + this.name = name; + } + + protected + void setLogTextPanel(LogTextPanel logTextPanel) { + this.logTextPanel = logTextPanel; + logTextPanel.setTextBackground(Color.white); + } + + public + void setOption(String option, String value) { + if (option.equalsIgnoreCase(COLOR_OPTION_FATAL)) + logTextPanel.setTextColor(Priority.FATAL,value); + if (option.equalsIgnoreCase(COLOR_OPTION_ERROR)) + logTextPanel.setTextColor(Priority.ERROR,value); + if (option.equalsIgnoreCase(COLOR_OPTION_WARN)) + logTextPanel.setTextColor(Priority.WARN,value); + if (option.equalsIgnoreCase(COLOR_OPTION_INFO)) + logTextPanel.setTextColor(Priority.INFO,value); + if (option.equalsIgnoreCase(COLOR_OPTION_DEBUG)) + logTextPanel.setTextColor(Priority.DEBUG,value); + if (option.equalsIgnoreCase(COLOR_OPTION_BACKGROUND)) + logTextPanel.setTextBackground(value); + if (option.equalsIgnoreCase(FONT_SIZE_OPTION)) + logTextPanel.setTextFontSize(Integer.parseInt(value)); + if (option.equalsIgnoreCase(FONT_NAME_OPTION)) + logTextPanel.setTextFontName(value); + if (option.equalsIgnoreCase(EVENT_BUFFER_SIZE_OPTION)) + logTextPanel.setEventBufferSize(Integer.parseInt(value)); + return; + } + + public + boolean requiresLayout() { + return true; + } + + + + class LogPublishingThread extends Thread { + + LogTextPanel logTextPanel; + ArrayList evts; + Priority triggerPrio; + long pubInterval; + + public LogPublishingThread(LogTextPanel logTextPanel, Priority triggerPrio, long pubInterval) { + this.logTextPanel = logTextPanel; + this.evts = new ArrayList(1000); + this.triggerPrio = triggerPrio; + this.pubInterval = pubInterval; + //this.setPriority(Thread.NORM_PRIORITY - 1); + this.start(); + } + + public void run() { + while(true) { + synchronized(evts) { + try { + evts.wait(pubInterval); + } + catch(InterruptedException e) {} + + logTextPanel.newEvents((EventBufferElement[])evts.toArray(new EventBufferElement[evts.size()])); + + evts.clear(); + } + } + + } + + public void publishEvent(Priority prio, String text) { + synchronized(evts) { + evts.add(new EventBufferElement(prio, text)); + if(triggerPrio != null && prio.isGreaterOrEqual(triggerPrio)) + evts.notify(); + } + } + } + +} // TextPaneAppender + +class EventBufferElement { + + public String text; + public Priority prio; + public int numLines; + + EventBufferElement(Priority prio, String text) { + this.prio = prio; + this.text = text; + numLines = 1; + int pos = pos = text.indexOf('\n', 0); + int len = text.length() - 1; + + while( (pos > 0) && (pos < len) ) + numLines++; + pos = text.indexOf('\n', pos + 1); + } +} + + diff --git a/contribs/JamesHouse/mail-2001-01-23 b/contribs/JamesHouse/mail-2001-01-23 new file mode 100644 index 0000000000..c8d94b707c --- /dev/null +++ b/contribs/JamesHouse/mail-2001-01-23 @@ -0,0 +1,87 @@ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +Delivered-To: urba-cgu@urbanet.ch +From: James House +To: Ceki Gulcu +Subject: RE: Buffering issues +Date: Tue, 23 Jan 2001 11:38:30 -0800 +X-Mailer: Internet Mail Service (5.5.2650.21) + + + +Ceki, + + +Most of the "speed" issues can be easily solved, as demonstrated in +the new versions of the files that are attached, and as described +here: + + +The "drawing" of the panel is time consuming. And let's face it: we +will never build a swing component that can re-draw itself thousands +of times per second - nor could the human eye keep up with that anyway +(60-ish redraws per second is the limit of what most humans can +perceive). + + +I think you'll agree that regardless of which choice of swing +components, the issue of not being able to draw more than 100 times +per second (if that) will be a constant. + + +Possible solutions to wasting a lot of time redrawing are: + * Redraw every N messages + * Redraw every N milliseconds + * Redraw when a message of a high priority is received + * Only redraw if the changes (new messages) are visible (depending on +scroll-bar position) + + + +I made some very small changes (which are some of what I outlined in +the previous e-mail as things on the to-do list), and you should be +able to see a great difference in performance. + + +In general the changes are: Use a "queue" to asynchronously deliver +the messages to the panel for updating, rather than having the calling +thread (the one generating the log message) be responsible for +re-drawing the panel - this frees up the thread to continue on without +waiting for the logging mechanism. The "queue" has a thread that +wakes up every N milliseconds, or when a message of a specified +priority arrives. It then delivers all queued messages to the panel, +which then redraws ONCE for the entire batch of queued messages IF the +new messages are visible in the display. + + +With the "tail" mechanism turned on (so that any new set of messages +forces a redraw, because the last message is always visible), the +panel can now log about a thousand messages in 1 second. With tail +turned off (so that redraw is only required if the panel is showing +the space the new messages will be printed), it can receive over a +100,000 messages in just a few seconds. Also, most of the flicker is +already eliminated. + + +Again, everything in the code is really "roughed in" - just there to +give the general idea, not necessarily to do things in the best way - +but I really feel that this kind of solution is what you'll have to +end up with in the long term. + + +James diff --git a/contribs/Jamie Tsao/JMSQueueAppender.java b/contribs/Jamie Tsao/JMSQueueAppender.java new file mode 100644 index 0000000000..9e762f5e29 --- /dev/null +++ b/contribs/Jamie Tsao/JMSQueueAppender.java @@ -0,0 +1,241 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.spi.ErrorHandler; +import org.apache.log4j.spi.ErrorCode; +import org.apache.log4j.helpers.LogLog; + +import java.util.Hashtable; +import java.util.Properties; +import javax.jms.*; +import javax.naming.InitialContext; +import javax.naming.Context; +import javax.naming.NameNotFoundException; +import javax.naming.NamingException; + +/** + * A Simple JMS (P2P) Queue Appender. + * + * @author Ceki Gülcü + * @author Jamie Tsao +*/ +public class JMSQueueAppender extends AppenderSkeleton { + + protected QueueConnection queueConnection; + protected QueueSession queueSession; + protected QueueSender queueSender; + protected Queue queue; + + String initialContextFactory; + String providerUrl; + String queueBindingName; + String queueConnectionFactoryBindingName; + + public + JMSQueueAppender() { + } + + + /** + * The InitialContextFactory option takes a string value. + * Its value, along with the ProviderUrl option will be used + * to get the InitialContext. + */ + public void setInitialContextFactory(String initialContextFactory) { + this.initialContextFactory = initialContextFactory; + } + + /** + * Returns the value of the InitialContextFactory option. + */ + public String getInitialContextFactory() { + return initialContextFactory; + } + + /** + * The ProviderUrl option takes a string value. + * Its value, along with the InitialContextFactory option will be used + * to get the InitialContext. + */ + public void setProviderUrl(String providerUrl) { + this.providerUrl = providerUrl; + } + + /** + * Returns the value of the ProviderUrl option. + */ + public String getProviderUrl() { + return providerUrl; + } + + /** + * The QueueConnectionFactoryBindingName option takes a + * string value. Its value will be used to lookup the appropriate + * QueueConnectionFactory from the JNDI context. + */ + public void setQueueConnectionFactoryBindingName(String queueConnectionFactoryBindingName) { + this.queueConnectionFactoryBindingName = queueConnectionFactoryBindingName; + } + + /** + * Returns the value of the QueueConnectionFactoryBindingName option. + */ + public String getQueueConnectionFactoryBindingName() { + return queueConnectionFactoryBindingName; + } + + /** + * The QueueBindingName option takes a + * string value. Its value will be used to lookup the appropriate + * destination Queue from the JNDI context. + */ + public void setQueueBindingName(String queueBindingName) { + this.queueBindingName = queueBindingName; + } + + /** + Returns the value of the QueueBindingName option. + */ + public String getQueueBindingName() { + return queueBindingName; + } + + + /** + * Overriding this method to activate the options for this class + * i.e. Looking up the Connection factory ... + */ + public void activateOptions() { + + QueueConnectionFactory queueConnectionFactory; + + try { + + Context ctx = getInitialContext(); + queueConnectionFactory = (QueueConnectionFactory) ctx.lookup(queueConnectionFactoryBindingName); + queueConnection = queueConnectionFactory.createQueueConnection(); + + queueSession = queueConnection.createQueueSession(false, + Session.AUTO_ACKNOWLEDGE); + + Queue queue = (Queue) ctx.lookup(queueBindingName); + queueSender = queueSession.createSender(queue); + + queueConnection.start(); + + ctx.close(); + + } catch(Exception e) { + errorHandler.error("Error while activating options for appender named ["+name+ + "].", e, ErrorCode.GENERIC_FAILURE); + } + } + + protected InitialContext getInitialContext() throws NamingException { + try { + Hashtable ht = new Hashtable(); + + //Populate property hashtable with data to retrieve the context. + ht.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory); + ht.put(Context.PROVIDER_URL, providerUrl); + + return (new InitialContext(ht)); + + } catch (NamingException ne) { + LogLog.error("Could not get initial context with ["+initialContextFactory + "] and [" + providerUrl + "]."); + throw ne; + } + } + + + protected boolean checkEntryConditions() { + + String fail = null; + + if(this.queueConnection == null) { + fail = "No QueueConnection"; + } else if(this.queueSession == null) { + fail = "No QueueSession"; + } else if(this.queueSender == null) { + fail = "No QueueSender"; + } + + if(fail != null) { + errorHandler.error(fail +" for JMSQueueAppender named ["+name+"]."); + return false; + } else { + return true; + } + } + + /** + * Close this JMSQueueAppender. Closing releases all resources used by the + * appender. A closed appender cannot be re-opened. + */ + public synchronized // avoid concurrent append and close operations + void close() { + + if(this.closed) + return; + + LogLog.debug("Closing appender ["+name+"]."); + this.closed = true; + + try { + if(queueSession != null) + queueSession.close(); + if(queueConnection != null) + queueConnection.close(); + } catch(Exception e) { + LogLog.error("Error while closing JMSQueueAppender ["+name+"].", e); + } + + // Help garbage collection + queueSender = null; + queueSession = null; + queueConnection = null; + } + + /** + * This method called by {@link AppenderSkeleton#doAppend} method to + * do most of the real appending work. The LoggingEvent will be + * be wrapped in an ObjectMessage to be put on the JMS queue. + */ + public void append(LoggingEvent event) { + + if(!checkEntryConditions()) { + return; + } + + try { + + ObjectMessage msg = queueSession.createObjectMessage(); + msg.setObject(event); + queueSender.send(msg); + + } catch(Exception e) { + errorHandler.error("Could not send message in JMSQueueAppender ["+name+"].", e, + ErrorCode.GENERIC_FAILURE); + } + } + + public boolean requiresLayout() { + return false; + } +} \ No newline at end of file diff --git a/contribs/Jamie Tsao/mail-2001-06-20 b/contribs/Jamie Tsao/mail-2001-06-20 new file mode 100644 index 0000000000..555309e549 --- /dev/null +++ b/contribs/Jamie Tsao/mail-2001-06-20 @@ -0,0 +1,28 @@ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +Hi, + +I have written a JMSQueueAppender that essentially logs to a JMS Queue +(Point 2 Point). The JMSAppender currently packaged with log4j logs to +a JMS Topic (I would rename it JMSTopicAppender). I also made it so +that the InitialContextFactory and ProviderUrl are configurable appender +options. I would like to submit this to Apache. + +Thanks, + +Jamie Tsao \ No newline at end of file diff --git a/contribs/JimMoore/LoggingOutputStream.java b/contribs/JimMoore/LoggingOutputStream.java new file mode 100644 index 0000000000..bc084b30db --- /dev/null +++ b/contribs/JimMoore/LoggingOutputStream.java @@ -0,0 +1,210 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import java.io.*; +import org.apache.log4j.*; + + +/** + * An OutputStream that flushes out to a Category.

+ * + * Note that no data is written out to the Category until the stream is + * flushed or closed.

+ * + * Example:

+ * // make sure everything sent to System.err is logged
+ * System.setErr(new PrintStream(new LoggingOutputStream(Category.getRoot(), Priority.WARN), true));
+ * 
+ * // make sure everything sent to System.out is also logged
+ * System.setOut(new PrintStream(new LoggingOutputStream(Category.getRoot(), Priority.INFO), true));
+ * 
+ * + * @author Jim Moore + * @see Category + */ +public class LoggingOutputStream extends OutputStream { + protected static final String LINE_SEPERATOR = System.getProperty("line.separator"); + + + /** + * Used to maintain the contract of {@link #close()}. + */ + protected boolean hasBeenClosed = false; + + /** + * The internal buffer where data is stored. + */ + protected byte[] buf; + + /** + * The number of valid bytes in the buffer. This value is always + * in the range 0 through buf.length; elements + * buf[0] through buf[count-1] contain valid + * byte data. + */ + protected int count; + + + /** + * Remembers the size of the buffer for speed. + */ + private int bufLength; + + /** + * The default number of bytes in the buffer. =2048 + */ + public static final int DEFAULT_BUFFER_LENGTH = 2048; + + + /** + * The category to write to. + */ + protected Category category; + + /** + * The priority to use when writing to the Category. + */ + protected Priority priority; + + + private LoggingOutputStream() { + // illegal + } + + + /** + * Creates the LoggingOutputStream to flush to the given Category. + * + * @param cat the Category to write to + * + * @param priority the Priority to use when writing to the Category + * + * @exception IllegalArgumentException + * if cat == null or priority == null + */ + public LoggingOutputStream(Category cat, Priority priority) + throws IllegalArgumentException { + if (cat == null) { + throw new IllegalArgumentException("cat == null"); + } + if (priority == null) { + throw new IllegalArgumentException("priority == null"); + } + + this.priority = priority; + category = cat; + bufLength = DEFAULT_BUFFER_LENGTH; + buf = new byte[DEFAULT_BUFFER_LENGTH]; + count = 0; + } + + + /** + * Closes this output stream and releases any system resources + * associated with this stream. The general contract of close + * is that it closes the output stream. A closed stream cannot perform + * output operations and cannot be reopened. + */ + public void close() { + flush(); + hasBeenClosed = true; + } + + + /** + * Writes the specified byte to this output stream. The general + * contract for write is that one byte is written + * to the output stream. The byte to be written is the eight + * low-order bits of the argument b. The 24 + * high-order bits of b are ignored. + * + * @param b the byte to write + * + * @exception IOException + * if an I/O error occurs. In particular, + * an IOException may be thrown if the + * output stream has been closed. + */ + public void write(final int b) throws IOException { + if (hasBeenClosed) { + throw new IOException("The stream has been closed."); + } + + // don't log nulls + if (b == 0) { + return; + } + + // would this be writing past the buffer? + if (count == bufLength) { + // grow the buffer + final int newBufLength = bufLength+DEFAULT_BUFFER_LENGTH; + final byte[] newBuf = new byte[newBufLength]; + + System.arraycopy(buf, 0, newBuf, 0, bufLength); + + buf = newBuf; + bufLength = newBufLength; + } + + buf[count] = (byte)b; + count++; + } + + + /** + * Flushes this output stream and forces any buffered output bytes + * to be written out. The general contract of flush is + * that calling it is an indication that, if any bytes previously + * written have been buffered by the implementation of the output + * stream, such bytes should immediately be written to their + * intended destination. + */ + public void flush() { + if (count == 0) { + return; + } + + // don't print out blank lines; flushing from PrintStream puts out these + if (count == LINE_SEPERATOR.length()) { + if ( ((char)buf[0]) == LINE_SEPERATOR.charAt(0) && + ( ( count == 1 ) || // <- Unix & Mac, -> Windows + ( (count == 2) && ((char)buf[1]) == LINE_SEPERATOR.charAt(1) ) ) ) { + reset(); + return; + } + } + + final byte[] theBytes = new byte[count]; + + System.arraycopy(buf, 0, theBytes, 0, count); + + category.log(priority, new String(theBytes)); + + reset(); + } + + + private void reset() { + // not resetting the buffer -- assuming that if it grew that it + // will likely grow similarly again + count = 0; + } + +} + diff --git a/contribs/JimMoore/mail-2001-03-12T1326 b/contribs/JimMoore/mail-2001-03-12T1326 new file mode 100644 index 0000000000..490b848481 --- /dev/null +++ b/contribs/JimMoore/mail-2001-03-12T1326 @@ -0,0 +1,56 @@ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +Copied from: +http://www.mail-archive.com/log4j-user@jakarta.apache.org/msg00430.html + +-------------------------------------------------------------------------------- +diverting System.stderr/stdout into log4j +-------------------------------------------------------------------------------- + +From: Joseph Panico +Subject: diverting System.stderr/stdout into log4j +Date: Mon, 12 Mar 2001 13:26:41 -0800 + +-------------------------------------------------------------------------------- + +Folks, + +We use a number of third-party packages that do stderr.print... at various +random places in their code. I'm finding it quite useful to divert these +messages into our log4j heirarchy. I do this by replacing stderr/stdout with +my own PrintStreams that log the lines to a special log4j Category-- as +suggested on this list a while back. The only fly-in-the-ointment with this +scheme is LogLog. If there is a problem with log4j such that it cannot log +for some reason, then log4j internals use LogLog to attempt to print an +error message. This obviously leads to an infinite recursion. Has anyone +else been bothered by this? Would it make sense to add interface to LogLog +which would set the PrintStream it uses to log its error messages to? + +thanks for any ideas + +joe + +_________________________________________________________________ +Get your FREE download of MSN Explorer at http://explorer.msn.com + + +--------------------------------------------------------------------- +To unsubscribe, e-mail: log4j-user-unsubscribe@jakarta.apache.org +For additional commands, e-mail: log4j-user-help@jakarta.apache.org + + diff --git a/contribs/JimMoore/mail-2001-03-12T1454 b/contribs/JimMoore/mail-2001-03-12T1454 new file mode 100644 index 0000000000..f7b232f04a --- /dev/null +++ b/contribs/JimMoore/mail-2001-03-12T1454 @@ -0,0 +1,127 @@ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +Copied from: +http://www.mail-archive.com/log4j-user@jakarta.apache.org/msg00433.html + +-------------------------------------------------------------------------------- +RE: diverting System.stderr/stdout into log4j +-------------------------------------------------------------------------------- + +From: Jim Moore +Subject: RE: diverting System.stderr/stdout into log4j +Date: Mon, 12 Mar 2001 14:54:13 -0800 + +-------------------------------------------------------------------------------- + +It doesn't. I haven't worried about it, since log4j doesn't contain any +bugs and therefore it would never happen... :) + +Probably the best way to handle it is to add a +LogLog.setPrintStream(PrintStream) method, so you can do something like: + +// remember STDERR +PrintStream se = System.err; + +// make sure everything sent to System.err is logged +System.setErr(new PrintStream(new LoggingOutputStream(Category.getRoot(), + Priority.WARN), true)); + +// make sure everything sent to System.out is also logged +System.setOut(new PrintStream(new LoggingOutputStream(Category.getRoot(), + Priority.INFO), true)); + +// prevent infinate recursion in LogLog +LogLog.setPrintStream(se); + + +I can't think of any other way to do it in the current version besides +getting extremely kludgey by checking the stack to see if it's being called +from LogLog and logging out the the "real" STDERR then in the +LoggingOutputStream. It can be done on the theory that LogLog wouldn't be +called very often, but still... + +-Jim Moore + + +-----Original Message----- +From: Ceki Gülcü [mailto:cgu@qos.ch] +Sent: Monday, March 12, 2001 5:15 PM +To: LOG4J Users Mailing List +Subject: RE: diverting System.stderr/stdout into log4j + + +Jim, Joseph, + +Here is a link containing Jim's code: + +http://marc.theaimsgroup.com/?l=log4j-user&m=98097669218571&w=2 + +How does this code handle the infinite recursion problem mentioned by +Joseph? Ceki + +At 17:03 12.03.2001 -0500, Jim Moore wrote: +>Go to the mailing list archives (theAimsGroup.com is the best) and search +>for the thread with the subject of "Capturing System.err" +> +>-Jim Moore +>"I think so, Brain; but if we gave peas a chance, won't the lima beans get +>jealous?" - Pinky +> +> +>-----Original Message----- +>From: Joseph Panico [mailto:joe_panico@hotmail.com] +>Sent: Monday, March 12, 2001 4:43 PM +>To: log4j-user@jakarta.apache.org +>Subject: diverting System.stderr/stdout into log4j +> +> +>Folks, +> +>We use a number of third-party packages that do stderr.print... at various +>random places in their code. I'm finding it quite useful to divert these +>messages into our log4j heirarchy. I do this by replacing stderr/stdout +with +> +>my own PrintStreams that log the lines to a special log4j Category-- as +>suggested on this list a while back. The only fly-in-the-ointment with this + +>scheme is LogLog. If there is a problem with log4j such that it cannot log +>for some reason, then log4j internals use LogLog to attempt to print an +>error message. This obviously leads to an infinite recursion. Has anyone +>else been bothered by this? Would it make sense to add interface to LogLog +>which would set the PrintStream it uses to log its error messages to? +> +>thanks for any ideas +> +>joe + +I hope to see you at my ApacheCon 2001 presentation +entitled "Log4j, A Logging Package for Java". + +See http://ApacheCon.Com/2001/US/ for more details. + +---- +Ceki Gülcü Web: http://qos.ch +av. de Rumine 5 email: cgu@qos.ch (preferred) +CH-1005 Lausanne ceki_gulcu@yahoo.com +Switzerland Tel: ++41 21 351 23 15 + +--------------------------------------------------------------------- +To unsubscribe, e-mail: log4j-user-unsubscribe@jakarta.apache.org +For additional commands, e-mail: log4j-user-help@jakarta.apache.org + + diff --git a/contribs/JimMoore/mail-2001-03-13T0646 b/contribs/JimMoore/mail-2001-03-13T0646 new file mode 100644 index 0000000000..39e54c2121 --- /dev/null +++ b/contribs/JimMoore/mail-2001-03-13T0646 @@ -0,0 +1,229 @@ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +Copied from +http://www.mail-archive.com/log4j-user@jakarta.apache.org/msg00445.html + +-------------------------------------------------------------------------------- +RE: diverting System.stderr/stdout into log4j +-------------------------------------------------------------------------------- + +From: Michael Smith +Subject: RE: diverting System.stderr/stdout into log4j +Date: Tue, 13 Mar 2001 06:46:04 -0800 + +-------------------------------------------------------------------------------- + +There is another way! + +In LogLog, completely ignore System.err. Instead, use the following to get +the standard error stream: + +PrintStream err = + new PrintStream(new FileOutputStream(FileDescriptor.err)); + +When you use System.setErr, it changes System.err, but not +FileDescriptor.err, which maintains a descriptor for the original error +stream. + +michael + +For a sample program to test this, see below: + +import java.io.*; + +public class Stderr { + + public static void main(String[] args) { + + // create a print stream to represent a redirect + PrintStream nonStandardErr = + new PrintStream(new ByteArrayOutputStream()); + + // Redirect standard out and standard err + System.setOut(nonStandardErr); + System.setErr(nonStandardErr); + + // attempt to print something + System.err.println("You should *not* see this on the console!"); + + // the stuff that would appear in LogLog + PrintStream logLogOut = + new PrintStream(new FileOutputStream(FileDescriptor.err)); + + // attempt to print something + logLogOut.println("You *should* see this on the console!"); + } +} + + + +> -----Original Message----- +> From: Ceki Gülcü [mailto:cgu@qos.ch] +> Sent: Monday, March 12, 2001 7:18 PM +> To: LOG4J Users Mailing List +> Subject: RE: diverting System.stderr/stdout into log4j +> +> +> +> Hate to follow up on myself, but the System.setErr method +> reassigns the System.err variable. This can be deduced without +> experimentation because the user calls the System.err variable +> directly to print to the console, whatever it might be. Thus, the +> reference itself must change to allow the System.err variable to +> point to the new target stream. +> +> The funny part is that the err variable is declared 'public +> final' in the JDK source code. The setErr method makes a call to +> setErr0 which is declared as being 'native'. It looks like the +> native part is circumventing the JDK restrictions. I find this +> quite entertaining. Ceki +> +> At 00:58 13.03.2001 +0100, Ceki Gülcü wrote: +> +> >Running the risk of disappointing you here, although not full of +> bugs, log4j is not bug-free as bugs creep out regularly. They +> just get corrected quickly before many people are affected by them. +> > +> >The PrintStream se = System.err; LogLog.setPrintStream(see); +> combination is simple and rather bright. I initially overlooked +> the PrintStream se = System.err; part, making me think that a +> lot of code needed to be modified to cater for the redirected +> console case. The remedy looked worse than the illness. My fears +> are largely unfounded and the solution should work quite well if +> one is careful. +> > +> >Regards, Ceki +> > +> >ps: I wonder if System.err always refers to the real STDERR or +> if really gets reassigned with the setErr call. It's easy to find out... +> > +> >At 23:20 12.03.2001 +0000, Joseph Panico wrote: +> >>Of course log4j is completely bug free, but that doesn't +> preclude user error. For instance, I neglected to add appenders +> in my config file (actually I intentionally left them out, +> thinking that would simply turn off logging) and then log4j went +> into an infinite loop. The setPrintStream makes sense to me. +> >> +> >>joe +> >> +> >> +> >>>From: Jim Moore +> >>>Reply-To: "LOG4J Users Mailing List" +> >>>To: 'LOG4J Users Mailing List' +> >>>Subject: RE: diverting System.stderr/stdout into log4j +> >>>Date: Mon, 12 Mar 2001 18:10:37 -0500 +> >>> +> >>>It doesn't. I haven't worried about it, since log4j doesn't +> contain any +> >>>bugs and therefore it would never happen... :) +> >>> +> >>>Probably the best way to handle it is to add a +> >>>LogLog.setPrintStream(PrintStream) method, so you can do +> something like: +> >>> +> >>>// remember STDERR +> >>>PrintStream se = System.err; +> >>> +> >>>// make sure everything sent to System.err is logged +> >>>System.setErr(new PrintStream(new +> LoggingOutputStream(Category.getRoot(), +> >>> Priority.WARN), true)); +> >>> +> >>>// make sure everything sent to System.out is also logged +> >>>System.setOut(new PrintStream(new +> LoggingOutputStream(Category.getRoot(), +> >>> Priority.INFO), true)); +> >>> +> >>>// prevent infinate recursion in LogLog +> >>>LogLog.setPrintStream(se); +> >>> +> >>> +> >>>I can't think of any other way to do it in the current version besides +> >>>getting extremely kludgey by checking the stack to see if it's +> being called +> >>>from LogLog and logging out the the "real" STDERR then in the +> >>>LoggingOutputStream. It can be done on the theory that LogLog +> wouldn't be +> >>>called very often, but still... +> >>> +> >>>-Jim Moore +> >>> +> >>> +> >>>-----Original Message----- +> >>>From: Ceki Gülcü [mailto:cgu@qos.ch] +> >>>Sent: Monday, March 12, 2001 5:15 PM +> >>>To: LOG4J Users Mailing List +> >>>Subject: RE: diverting System.stderr/stdout into log4j +> >>> +> >>> +> >>>Jim, Joseph, +> >>> +> >>>Here is a link containing Jim's code: +> >>> +> >>>http://marc.theaimsgroup.com/?l=log4j-user&m=98097669218571&w=2 +> >>> +> >>>How does this code handle the infinite recursion problem mentioned by +> >>>Joseph? Ceki +> >>> +> >>>At 17:03 12.03.2001 -0500, Jim Moore wrote: +> >>>>Go to the mailing list archives (theAimsGroup.com is the +> best) and search +> >>>>for the thread with the subject of "Capturing System.err" +> >>>> +> >>>>-Jim Moore +> >>>>"I think so, Brain; but if we gave peas a chance, won't the +> lima beans get +> >>>>jealous?" - Pinky +> >>>> +> >>>> +> >>>>-----Original Message----- +> >>>>From: Joseph Panico [mailto:joe_panico@hotmail.com] +> >>>>Sent: Monday, March 12, 2001 4:43 PM +> >>>>To: log4j-user@jakarta.apache.org +> >>>>Subject: diverting System.stderr/stdout into log4j +> >>>> +> >>>> +> >>>>Folks, +> >>>> +> >>>>We use a number of third-party packages that do +> stderr.print... at various +> >>>>random places in their code. I'm finding it quite useful to +> divert these +> >>>>messages into our log4j heirarchy. I do this by replacing +> stderr/stdout +> >>>with +> >>>> +> >>>>my own PrintStreams that log the lines to a special log4j +> Category-- as +> >>>>suggested on this list a while back. The only +> fly-in-the-ointment with this +> >>> +> >>>>scheme is LogLog. If there is a problem with log4j such that +> it cannot log +> >>>>for some reason, then log4j internals use LogLog to attempt +> to print an +> >>>>error message. This obviously leads to an infinite recursion. +> Has anyone +> >>>>else been bothered by this? Would it make sense to add +> interface to LogLog +> >>>>which would set the PrintStream it uses to log its error messages to? +> >>>> +> >>>>thanks for any ideas +> >>>> +> >>>>joe + + diff --git a/contribs/KevinSteppe/CompositeRollingAppender.java b/contribs/KevinSteppe/CompositeRollingAppender.java new file mode 100644 index 0000000000..3957f1658e --- /dev/null +++ b/contribs/KevinSteppe/CompositeRollingAppender.java @@ -0,0 +1,707 @@ +package org.apache.log4j; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.log4j.RollingCalendar; +import org.apache.log4j.helpers.OptionConverter; +import org.apache.log4j.helpers.QuietWriter; +import org.apache.log4j.helpers.CountingQuietWriter; +import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.spi.LoggingEvent; + +import java.util.Date; +import java.io.IOException; +import java.io.Writer; +import java.text.SimpleDateFormat; +import java.io.File; +import java.io.FilenameFilter; + +/** + *

CompositeRollingAppender combines RollingFileAppender and DailyRollingFileAppender
+ * It can function as either or do both at the same time (making size + * based rolling files like RollingFileAppender until a data/time boundary + * is crossed at which time it rolls all of those files as per the DailyRollingFileAppender) + * based on the setting for rollingStyle.
+ *
+ * To use CompositeRollingAppender to roll log files as they reach a certain + * size (like RollingFileAppender), set rollingStyle=1 (@see config.size)
+ * To use CompositeRollingAppender to roll log files at certain time intervals + * (daily for example), set rollingStyle=2 and a datePattern (@see config.time)
+ * To have CompositeRollingAppender roll log files at a certain size AND rename those + * according to time intervals, set rollingStyle=3 (@see config.composite)
+ * + *

A of few additional optional features have been added:
+ * -- Attach date pattern for current log file (@see staticLogFileName)
+ * -- Backup number increments for newer files (@see countDirection)
+ * -- Infinite number of backups by file size (@see maxSizeRollBackups)
+ *
+ *

A few notes and warnings: For large or infinite number of backups + * countDirection > 0 is highly recommended, with staticLogFileName = false if + * time based rolling is also used -- this will reduce the number of file renamings + * to few or none. Changing staticLogFileName or countDirection without clearing + * the directory could have nasty side effects. If Date/Time based rolling + * is enabled, CompositeRollingAppender will attempt to roll existing files + * in the directory without a date/time tag based on the last modified date + * of the base log files last modification.
+ *
+ *

A maximum number of backups based on date/time boundries would be nice + * but is not yet implemented.
+ * + * @author Kevin Steppe + * @author Heinz Richter + * @author Eirik Lygre + * @author Ceki Gülcü + */ +public class CompositeRollingAppender extends org.apache.log4j.FileAppender +{ + // The code assumes that the following 'time' constants are in a increasing + // sequence. + static final int TOP_OF_TROUBLE=-1; + static final int TOP_OF_MINUTE = 0; + static final int TOP_OF_HOUR = 1; + static final int HALF_DAY = 2; + static final int TOP_OF_DAY = 3; + static final int TOP_OF_WEEK = 4; + static final int TOP_OF_MONTH = 5; + + /** Style of rolling to use */ + static final int BY_SIZE = 1; + static final int BY_DATE = 2; + static final int BY_COMPOSITE = 3; + + //Not currently used + static final String S_BY_SIZE = "Size"; + static final String S_BY_DATE = "Date"; + static final String S_BY_COMPOSITE = "Composite"; + + /** + The date pattern. By default, the pattern is set to + "'.'yyyy-MM-dd" meaning daily rollover. + */ + private String datePattern = "'.'yyyy-MM-dd"; + + /** The actual formatted filename that is currently being written to + or will be the file transferred to on roll over + (based on staticLogFileName). */ + private String scheduledFilename = null; + + /** The timestamp when we shall next recompute the filename. */ + private long nextCheck = System.currentTimeMillis () - 1; + + /** Holds date of last roll over */ + Date now = new Date(); + + SimpleDateFormat sdf; + + /** Helper class to determine next rollover time */ + RollingCalendar rc = new RollingCalendar(); + + /** Current period for roll overs */ + int checkPeriod = TOP_OF_TROUBLE; + + /** The default maximum file size is 10MB. */ + protected long maxFileSize = 10*1024*1024; + + /** There is zero backup files by default. */ + protected int maxSizeRollBackups = 0; + /** How many sized based backups have been made so far */ + protected int curSizeRollBackups = 0; + + /** not yet implemented */ + protected int maxTimeRollBackups = -1; + protected int curTimeRollBackups = 0; + + /** By default newer files have lower numbers. (countDirection < 0) + * ie. log.1 is most recent, log.5 is the 5th backup, etc... + * countDirection > 0 does the opposite ie. + * log.1 is the first backup made, log.5 is the 5th backup made, etc. + * For infinite backups use countDirection > 0 to reduce rollOver costs. + */ + protected int countDirection = -1; + + /** Style of rolling to Use. BY_SIZE (1), BY_DATE(2), BY COMPOSITE(3) */ + protected int rollingStyle = BY_COMPOSITE; + protected boolean rollDate = true; + protected boolean rollSize = true; + + /** By default file.log is always the current file. Optionally + * file.log.yyyy-mm-dd for current formated datePattern can by the currently + * logging file (or file.log.curSizeRollBackup or even + * file.log.yyyy-mm-dd.curSizeRollBackup) This will make time based roll + * overs with a large number of backups much faster -- it won't have to + * rename all the backups! + */ + protected boolean staticLogFileName = true; + + /** FileName provided in configuration. Used for rolling properly */ + protected String baseFileName; + + /** The default constructor does nothing. */ + public CompositeRollingAppender() { + } + + /** + Instantiate a CompositeRollingAppender and open the + file designated by filename. The opened filename will + become the ouput destination for this appender. + */ + public CompositeRollingAppender (Layout layout, String filename, + String datePattern) throws IOException { + this(layout, filename, datePattern, true); + } + + /** + Instantiate a CompositeRollingAppender and open the file designated by + filename. The opened filename will become the ouput + destination for this appender. + +

If the append parameter is true, the file will be + appended to. Otherwise, the file desginated by + filename will be truncated before being opened. + */ + public CompositeRollingAppender(Layout layout, String filename, boolean append) + throws IOException { + super(layout, filename, append); + } + + /** + Instantiate a CompositeRollingAppender and open the file designated by + filename. The opened filename will become the ouput + destination for this appender. + */ + public CompositeRollingAppender (Layout layout, String filename, + String datePattern, boolean append) throws IOException { + super(layout, filename, append); + this.datePattern = datePattern; + activateOptions(); + } + /** + Instantiate a CompositeRollingAppender and open the file designated by + filename. The opened filename will become the output + destination for this appender. + +

The file will be appended to. DatePattern is default. + */ + public CompositeRollingAppender(Layout layout, String filename) throws IOException { + super(layout, filename); + } + + /** + The DatePattern takes a string in the same format as + expected by {@link SimpleDateFormat}. This options determines the + rollover schedule. + */ + public void setDatePattern(String pattern) { + datePattern = pattern; + } + + /** Returns the value of the DatePattern option. */ + public String getDatePattern() { + return datePattern; + } + + /** + Returns the value of the maxSizeRollBackups option. + */ + public int getMaxSizeRollBackups() { + return maxSizeRollBackups; + } + + /** + Get the maximum size that the output file is allowed to reach + before being rolled over to backup files. + + @since 1.1 + */ + public long getMaximumFileSize() { + return maxFileSize; + } + + /** +

Set the maximum number of backup files to keep around based on file size. + +

The MaxSizeRollBackups option determines how many backup + files are kept before the oldest is erased. This option takes + an integer value. If set to zero, then there will be no + backup files and the log file will be truncated when it reaches + MaxFileSize. If a negative number is supplied then + no deletions will be made. Note that this could result in + very slow performance as a large number of files are rolled over unless + {@link #setCountDirection} up is used. + +

The maximum applys to -each- time based group of files and -not- the total. + Using a daily roll the maximum total files would be (#days run) * (maxSizeRollBackups) + + */ + public void setMaxSizeRollBackups(int maxBackups) { + maxSizeRollBackups = maxBackups; + } + + /** + Set the maximum size that the output file is allowed to reach + before being rolled over to backup files. + +

This method is equivalent to {@link #setMaxFileSize} except + that it is required for differentiating the setter taking a + long argument from the setter taking a + String argument by the JavaBeans {@link + java.beans.Introspector Introspector}. + + @see #setMaxFileSize(String) + */ + public void setMaxFileSize(long maxFileSize) { + this.maxFileSize = maxFileSize; + } + + /** + Set the maximum size that the output file is allowed to reach + before being rolled over to backup files. + +

This method is equivalent to {@link #setMaxFileSize} except + that it is required for differentiating the setter taking a + long argument from the setter taking a + String argument by the JavaBeans {@link + java.beans.Introspector Introspector}. + + @see #setMaxFileSize(String) + */ + public void setMaximumFileSize(long maxFileSize) { + this.maxFileSize = maxFileSize; + } + + /** + Set the maximum size that the output file is allowed to reach + before being rolled over to backup files. + +

In configuration files, the MaxFileSize option takes an + long integer in the range 0 - 2^63. You can specify the value + with the suffixes "KB", "MB" or "GB" so that the integer is + interpreted being expressed respectively in kilobytes, megabytes + or gigabytes. For example, the value "10KB" will be interpreted + as 10240. + */ + public void setMaxFileSize(String value) { + maxFileSize = OptionConverter.toFileSize(value, maxFileSize + 1); + } + + protected void setQWForFiles(Writer writer) { + qw = new CountingQuietWriter(writer, errorHandler); + } + + //Taken verbatum from DailyRollingFileAppender + int computeCheckPeriod() { + RollingCalendar c = new RollingCalendar(); + // set sate to 1970-01-01 00:00:00 GMT + Date epoch = new Date(0); + if(datePattern != null) { + for(int i = TOP_OF_MINUTE; i <= TOP_OF_MONTH; i++) { + String r0 = sdf.format(epoch); + c.setType(i); + Date next = new Date(c.getNextCheckMillis(epoch)); + String r1 = sdf.format(next); + //LogLog.debug("Type = "+i+", r0 = "+r0+", r1 = "+r1); + if(r0 != null && r1 != null && !r0.equals(r1)) { + return i; + } + } + } + return TOP_OF_TROUBLE; // Deliberately head for trouble... + } + + //Now for the new stuff + /** + * Handles append time behavior for CompositeRollingAppender. This checks + * if a roll over either by date (checked first) or time (checked second) + * is need and then appends to the file last. + */ + protected void subAppend(LoggingEvent event) { + + if (rollDate) { + long n = System.currentTimeMillis(); + if (n >= nextCheck) { + now.setTime(n); + nextCheck = rc.getNextCheckMillis(now); + + rollOverTime(); + } + } + + if (rollSize) { + if ((fileName != null) && ((CountingQuietWriter) qw).getCount() >= maxFileSize) { + rollOverSize(); + } + } + + super.subAppend(event); + } + + public void setFile(String file) + { + baseFileName = file.trim(); + fileName = file.trim(); + } + + /** + * Creates and opens the file for logging. If staticLogFileName + * is false then the fully qualified name is determined and used. + */ + public synchronized void setFile(String fileName, boolean append) throws IOException { + if (!staticLogFileName) { + scheduledFilename = fileName = fileName.trim() + sdf.format(now); + if (countDirection > 0) { + scheduledFilename = fileName = fileName + '.' + (++curSizeRollBackups); + } + } + + super.setFile(fileName, append); + if(append) { + File f = new File(fileName); + ((CountingQuietWriter) qw).setCount(f.length()); + } + } + + public int getCountDirection() { + return countDirection; + } + + public void setCountDirection(int direction) { + countDirection = direction; + } + + public int getRollingStyle () { + return rollingStyle; + } + + public void setRollingStyle(int style) { + rollingStyle = style; + switch (rollingStyle) { + case BY_SIZE: + rollDate = false; + rollSize = true; + break; + case BY_DATE: + rollDate = true; + rollSize = false; + break; + case BY_COMPOSITE: + rollDate = true; + rollSize = true; + break; + default: + errorHandler.error("Invalid rolling Style, use 1 (by size only), 2 (by date only) or 3 (both)"); + } + } + +/* + public void setRollingStyle(String style) { + if (style == S_BY_SIZE) { + rollingStyle = BY_SIZE; + } + else if (style == S_BY_DATE) { + rollingStyle = BY_DATE; + } + else if (style == S_BY_COMPOSITE) { + rollingStyle = BY_COMPOSITE; + } + } +*/ + public boolean getStaticLogFileName() { + return staticLogFileName; + } + + public void setStaticLogFileName(boolean s) { + staticLogFileName = s; + } + + public void setStaticLogFileName(String value) { + setStaticLogFileName(OptionConverter.toBoolean(value, true)); + } + + /** + * Initializes based on exisiting conditions at time of + * activateOptions. The following is done:
+ *
+ * A) determine curSizeRollBackups
+ * B) determine curTimeRollBackups (not implemented)
+ * C) initiates a roll over if needed for crossing a date boundary since + * the last run. + */ + protected void existingInit() { + + curSizeRollBackups = 0; + curTimeRollBackups = 0; + + //part A starts here + String filter; + if (staticLogFileName || !rollDate) { + filter = baseFileName + ".*"; + } + else { + filter = scheduledFilename + ".*"; + } + + File f = new File(baseFileName); + f = f.getParentFile(); + if (f == null) + f = new File("."); + + LogLog.debug("Searching for existing files in: " + f); + String[] files = f.list(); + + if (files != null) { + for (int i = 0; i < files.length; i++) { + if (!files[i].startsWith(baseFileName)) + continue; + + int index = files[i].lastIndexOf("."); + + if (staticLogFileName) { + int endLength = files[i].length() - index; + if (baseFileName.length() + endLength != files[i].length()) { + //file is probably scheduledFilename + .x so I don't care + continue; + } + } + + try { + int backup = Integer.parseInt(files[i].substring(index + 1, files[i].length())); + LogLog.debug("From file: " + files[i] + " -> " + backup); + if (backup > curSizeRollBackups) + curSizeRollBackups = backup; + } + catch (Exception e) { + //this happens when file.log -> file.log.yyyy-mm-dd which is normal + //when staticLogFileName == false + LogLog.debug("Encountered a backup file not ending in .x " + files[i]); + } + } + } + LogLog.debug("curSizeRollBackups starts at: " + curSizeRollBackups); + //part A ends here + + //part B not yet implemented + + //part C + if (staticLogFileName && rollDate) { + File old = new File(baseFileName); + if (old.exists()) { + Date last = new Date(old.lastModified()); + if (!(sdf.format(last).equals(sdf.format(now)))) { + scheduledFilename = baseFileName + sdf.format(last); + LogLog.debug("Initial roll over to: " + scheduledFilename); + rollOverTime(); + } + } + } + LogLog.debug("curSizeRollBackups after rollOver at: " + curSizeRollBackups); + //part C ends here + + } + + /** + * Sets initial conditions including date/time roll over information, first check, + * scheduledFilename, and calls existingInit to initialize + * the current # of backups. + */ + public void activateOptions() { + + //REMOVE removed rollDate from boolean to enable Alex's change + if(datePattern != null) { + now.setTime(System.currentTimeMillis()); + sdf = new SimpleDateFormat(datePattern); + int type = computeCheckPeriod(); + //printPeriodicity(type); + rc.setType(type); + //next line added as this removes the name check in rollOver + nextCheck = rc.getNextCheckMillis(now); + } else { + if (rollDate) + LogLog.error("Either DatePattern or rollingStyle options are not set for ["+ + name+"]."); + } + + existingInit(); + + super.activateOptions(); + + if (rollDate && fileName != null && scheduledFilename == null) + scheduledFilename = fileName + sdf.format(now); + } + + /** + Rollover the file(s) to date/time tagged file(s). + Opens the new file (through setFile) and resets curSizeRollBackups. + */ + protected void rollOverTime() { + + curTimeRollBackups++; + + //delete the old stuff here + + if (staticLogFileName) { + /* Compute filename, but only if datePattern is specified */ + if (datePattern == null) { + errorHandler.error("Missing DatePattern option in rollOver()."); + return; + } + + //is the new file name equivalent to the 'current' one + //something has gone wrong if we hit this -- we should only + //roll over if the new file will be different from the old + String dateFormat = sdf.format(now); + if (scheduledFilename.equals(fileName + dateFormat)) { + errorHandler.error("Compare " + scheduledFilename + " : " + fileName + dateFormat); + return; + } + + // close current file, and rename it to datedFilename + this.closeFile(); + + //we may have to roll over a large number of backups here + String from, to; + for (int i = 1; i <= curSizeRollBackups; i++) { + from = fileName + '.' + i; + to = scheduledFilename + '.' + i; + rollFile(from, to); + } + + rollFile(fileName, scheduledFilename); + } + + try { + // This will also close the file. This is OK since multiple + // close operations are safe. + curSizeRollBackups = 0; //We're cleared out the old date and are ready for the new + + //new scheduled name + scheduledFilename = fileName + sdf.format(now); + this.setFile(baseFileName, false); + } + catch(IOException e) { + errorHandler.error("setFile("+fileName+", false) call failed."); + } + + } + + /** Renames file from to file to. It + * also checks for existence of target file and deletes if it does. + */ + protected static void rollFile(String from, String to) { + File target = new File(to); + if (target.exists()) { + LogLog.debug("deleting existing target file: " + target); + target.delete(); + } + + File file = new File(from); + file.renameTo(target); + LogLog.debug(from +" -> "+ to); + } + + /** Delete's the specified file if it exists */ + protected static void deleteFile(String fileName) { + File file = new File(fileName); + if (file.exists()) { + file.delete(); + } + } + + /** + Implements roll overs base on file size. + +

If the maximum number of size based backups is reached + (curSizeRollBackups == maxSizeRollBackups + If countDirection < 0, then files + {File.1, ..., File.curSizeRollBackups -1} + are renamed to {File.2, ..., + File.curSizeRollBackups}. Moreover, File is + renamed File.1 and closed.
+ + A new file is created to receive further log output. + +

If maxSizeRollBackups is equal to zero, then the + File is truncated with no backup files created. + +

If maxSizeRollBackups < 0, then File is + renamed if needed and no files are deleted. + */ + + // synchronization not necessary since doAppend is alreasy synched + protected void rollOverSize() { + File file; + + this.closeFile(); // keep windows happy. + + LogLog.debug("rolling over count=" + ((CountingQuietWriter) qw).getCount()); + LogLog.debug("maxSizeRollBackups = " + maxSizeRollBackups); + LogLog.debug("curSizeRollBackups = " + curSizeRollBackups); + LogLog.debug("countDirection = " + countDirection); + + // If maxBackups <= 0, then there is no file renaming to be done. + if (maxSizeRollBackups != 0) { + + if (countDirection < 0) { + // Delete the oldest file, to keep Windows happy. + if (curSizeRollBackups == maxSizeRollBackups) { + deleteFile(fileName + '.' + maxSizeRollBackups); + curSizeRollBackups--; + } + + // Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3, 2} + for (int i = curSizeRollBackups; i >= 1; i--) { + rollFile((fileName + "." + i), (fileName + '.' + (i + 1))); + } + + curSizeRollBackups++; + // Rename fileName to fileName.1 + rollFile(fileName, fileName + ".1"); + + } //REMOVE This code branching for Alexander Cerna's request + else if (countDirection == 0) { + //rollFile based on date pattern + curSizeRollBackups++; + now.setTime(System.currentTimeMillis()); + scheduledFilename = fileName + sdf.format(now); + rollFile(fileName, scheduledFilename); + } + else { //countDirection > 0 + if (curSizeRollBackups >= maxSizeRollBackups && maxSizeRollBackups > 0) { + //delete the first and keep counting up. + int oldestFileIndex = curSizeRollBackups - maxSizeRollBackups + 1; + deleteFile(fileName + '.' + oldestFileIndex); + } + + if (staticLogFileName) { + curSizeRollBackups++; + rollFile(fileName, fileName + '.' + curSizeRollBackups); + } + } + } + + try { + // This will also close the file. This is OK since multiple + // close operations are safe. + this.setFile(baseFileName, false); + } + catch(IOException e) { + LogLog.error("setFile("+fileName+", false) call failed.", e); + } + } + +} \ No newline at end of file diff --git a/contribs/KevinSteppe/JDBCTest.java b/contribs/KevinSteppe/JDBCTest.java new file mode 100644 index 0000000000..8df3d18a23 --- /dev/null +++ b/contribs/KevinSteppe/JDBCTest.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.varia.test; + + +import org.apache.log4j.varia.JDBCAppender; +import org.apache.log4j.*; + + +public class JDBCTest +{ + public static void main (String argv[]) + { + try { + Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); + } + catch (Exception e) + { + e.printStackTrace(); + System.out.println(e.toString()); + } + + + Category rootLog = Category.getRoot(); + Layout layout = new PatternLayout("%p [%t] %c - %m%n"); + JDBCAppender appender = new JDBCAppender(); + appender.setLayout(layout); + appender.setOption(JDBCAppender.URL_OPTION, "jdbc:odbc:someDB"); + + + appender.setOption(JDBCAppender.USER_OPTION, "auser"); + appender.setOption(JDBCAppender.PASSWORD_OPTION, "thepassword"); + + + + rootLog.addAppender(appender); + + + try { + Category log = Category.getInstance("main"); + log.debug("Debug 1"); + Thread.sleep(500); + log.info("info 1"); + Thread.sleep(500); + log.warn("warn 1"); + Thread.sleep(500); + log.error("error 1"); + Thread.sleep(500); + log.fatal("fatal 1"); + Thread.sleep(500); + + + appender.setOption(JDBCAppender.BUFFER_OPTION, "5"); + log.debug("Debug 2"); + Thread.sleep(500); + log.info("info 2"); + Thread.sleep(500); + log.warn("warn 2"); + Thread.sleep(500); + log.error("error 2"); + Thread.sleep(500); + log.fatal("fatal 2"); + Thread.sleep(500); + + + appender.setOption(JDBCAppender.BUFFER_OPTION, "2"); + appender.setThreshold(Priority.WARN); + log.debug("Debug 3"); + Thread.sleep(500); + log.info("info 3"); + Thread.sleep(500); + log.warn("warn 3"); + Thread.sleep(500); + log.error("error 3"); + Thread.sleep(500); + log.fatal("fatal 3"); + } + catch (InterruptedException e) + { + System.out.println("Interrupted"); + } + } +} diff --git a/contribs/KevinSteppe/mail-2001-02-01 b/contribs/KevinSteppe/mail-2001-02-01 new file mode 100644 index 0000000000..0d6c947624 --- /dev/null +++ b/contribs/KevinSteppe/mail-2001-02-01 @@ -0,0 +1,559 @@ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +Delivered-To: urba-cgu@urbanet.ch +Mailing-List: contact log4j-user-help@jakarta.apache.org; run by ezmlm +List-Post: +List-Help: +List-Unsubscribe: +List-Subscribe: +Reply-To: "LOG4J Users Mailing List" +Delivered-To: mailing list log4j-user@jakarta.apache.org +Date: Thu, 01 Feb 2001 14:26:34 -0800 +From: Kevin Steppe +X-Mailer: Mozilla 4.76 [en] (Windows NT 5.0; U) +X-Accept-Language: en +To: LOG4J Users Mailing List +Subject: JDBC Appender +X-Spam-Rating: h31.sny.collab.net 1.6.2 0/1000/N + + +Ok, here it is. Since there will be differences in database schemas and +connection/execution methods, I wrote this with the intention that those +parts would be overriden by subclasses (that's what I'm doing for my +company), however it will work as is if you have a stored procedure +spLog @msg. I'm sure there are optimizations which could be done. + + +The code for org.apache.log4j.varia.JDBCAppender and +org.apache.log4j.varia.test.JDBCTest follow and files attached. At the +bottem is the SQL I used to test this on M$ SQL-Server. + + +I help this proves useful, +Kevin + + + + +package org.apache.log4j.varia; + + +import org.apache.log4j.*; +import org.apache.log4j.spi.*; + + +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + + +import java.sql.DriverManager; +import java.sql.Connection; +import java.sql.Statement; +import java.sql.SQLException; + + +/** + * Contribution from MD Data Direct. + * + * Implements an ArrayList buffer before storing messages to the DB. + * Override getSQL to fit your database schema (or implement spLog msg +on your DB) + * Override executeSQL to modify how DB connection and SQL execution is +made. + * + * @author: Kevin Steppe + */ +public class JDBCAppender extends org.apache.log4j.AppenderSkeleton + implements org.apache.log4j.Appender +{ + protected String databaseURL = "jdbc:odbc:myDB"; + protected String databaseUser = "me"; + protected String databasePassword = "mypassword"; + + + public static final String URL_OPTION = "URL"; + public static final String USER_OPTION = "User"; + public static final String PASSWORD_OPTION = "Password"; + public static final String BUFFER_OPTION = "Buffer"; + protected int bufferSize = 1; + protected List buffer; + + + public JDBCAppender() + { + super(); + buffer = new ArrayList(); + } + + + public void append(LoggingEvent event) + { + buffer.add(event); + + + if (buffer.size() >= bufferSize) + flushBuffer(); + } + + + public void close() + { + flushBuffer(); + this.closed = true; + } + + + public void setOption(String key, String value) + { + super.setOption(key, value); + + + if (key.equalsIgnoreCase(URL_OPTION)) + databaseURL = value; + else if (key.equalsIgnoreCase(USER_OPTION)) + databaseUser = value; + else if (key.equalsIgnoreCase(PASSWORD_OPTION)) + databasePassword = value; + else if (key.equalsIgnoreCase(BUFFER_OPTION)) + bufferSize = Integer.parseInt(value); + } + + + /** + * Override this to create the SQL needed for your DB schema + */ + protected String getSQL(LoggingEvent event) + { + String msg = this.layout.format(event); + String sql = "spLog '" + msg + "'"; + return sql; + } + + + /** + * Override this to provide an alertnate method of getting +connections (such as caching) + * This implementation creates a new connection and statement for +every execution which + * is very wastefull. One method to fix this is to open connections +at the start of + * flushBuffer() and close them at the end. MD Data uses a +connection pool outside + * of JDBCAppender which is accessed in the override of this method. + + + */ + protected void executeSQL(String sql) throws SQLException + { + Connection con = null; + Statement stmt = null; + + + try { + con = DriverManager.getConnection(databaseURL, databaseUser, +databasePassword); + stmt = con.createStatement(); + stmt.executeUpdate(sql); + } + catch (SQLException e) + { + if (con != null) + con.close(); + if (stmt != null) + stmt.close(); + + + throw e; + } + stmt.close(); + con.close(); + } + + + public void flushBuffer() + { + //Do the actual logging + for (Iterator i = buffer.iterator(); i.hasNext();) + { + try { + String sql = getSQL((LoggingEvent)i.next()); + executeSQL(sql); + } + catch (SQLException e) + { + errorHandler.error("Failed to excute sql", e, +ErrorCode.FLUSH_FAILURE); + } + } + buffer.clear(); + } + + + public void finalize() + { + close(); + } + + + public boolean requiresLayout() + { + return true; + } + + +} + + + +package org.apache.log4j.varia.test; + + +import org.apache.log4j.varia.JDBCAppender; +import org.apache.log4j.*; + + +public class JDBCTest +{ + public static void main (String argv[]) + { + try { + Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); + } + catch (Exception e) + { + e.printStackTrace(); + System.out.println(e.toString()); + } + + + Category rootLog = Category.getRoot(); + Layout layout = new PatternLayout("%p [%t] %c - %m%n"); + JDBCAppender appender = new JDBCAppender(); + appender.setLayout(layout); + appender.setOption(JDBCAppender.URL_OPTION, "jdbc:odbc:someDB"); + + + appender.setOption(JDBCAppender.USER_OPTION, "auser"); + appender.setOption(JDBCAppender.PASSWORD_OPTION, "thepassword"); + + + + rootLog.addAppender(appender); + + + try { + Category log = Category.getInstance("main"); + log.debug("Debug 1"); + Thread.sleep(500); + log.info("info 1"); + Thread.sleep(500); + log.warn("warn 1"); + Thread.sleep(500); + log.error("error 1"); + Thread.sleep(500); + log.fatal("fatal 1"); + Thread.sleep(500); + + + appender.setOption(JDBCAppender.BUFFER_OPTION, "5"); + log.debug("Debug 2"); + Thread.sleep(500); + log.info("info 2"); + Thread.sleep(500); + log.warn("warn 2"); + Thread.sleep(500); + log.error("error 2"); + Thread.sleep(500); + log.fatal("fatal 2"); + Thread.sleep(500); + + + appender.setOption(JDBCAppender.BUFFER_OPTION, "2"); + appender.setThreshold(Priority.WARN); + log.debug("Debug 3"); + Thread.sleep(500); + log.info("info 3"); + Thread.sleep(500); + log.warn("warn 3"); + Thread.sleep(500); + log.error("error 3"); + Thread.sleep(500); + log.fatal("fatal 3"); + } + catch (InterruptedException e) + { + System.out.println("Interrupted"); + } + } +} + + + +drop table JDBCAppenderTest +go +create table JDBCAppenderTest (EventID int identity, entrytime datetime, +message varchar(255)) + + +drop procedure spLog +go +create procedure spLog (@msg varchar(255)) as + insert into JDBCAppenderTest (message, entrytime) values (@msg, +getdate()) + + +select * from JDBCAppenderTest + + + +drop table JDBCAppenderTest +go +create table JDBCAppenderTest (EventID int identity, entrytime datetime, message varchar(255)) + + +drop procedure spLog +go +create procedure spLog (@msg varchar(255)) as + insert into JDBCAppenderTest (message, entrytime) values (@msg, getdate()) + + +select * from JDBCAppenderTest +package org.apache.log4j.varia; + + +import org.apache.log4j.*; +import org.apache.log4j.spi.*; + + +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + + +import java.sql.DriverManager; +import java.sql.Connection; +import java.sql.Statement; +import java.sql.SQLException; + + +/** + * Contribution from MD Data Direct. + * + * Implements an ArrayList buffer before storing messages to the DB. + * Override getSQL to fit your database schema (or implement spLog msg on your DB) + * Override executeSQL to modify how DB connection and SQL execution is made. + * + * @author: Kevin Steppe + */ +public class JDBCAppender extends org.apache.log4j.AppenderSkeleton + implements org.apache.log4j.Appender +{ + protected String databaseURL = "jdbc:odbc:myDB"; + protected String databaseUser = "me"; + protected String databasePassword = "mypassword"; + + public static final String URL_OPTION = "URL"; + public static final String USER_OPTION = "User"; + public static final String PASSWORD_OPTION = "Password"; + public static final String BUFFER_OPTION = "Buffer"; + protected int bufferSize = 1; + protected List buffer; + + public JDBCAppender() + { + super(); + buffer = new ArrayList(); + } + + public void append(LoggingEvent event) + { + buffer.add(event); + + if (buffer.size() >= bufferSize) + flushBuffer(); + } + + + public void close() + { + flushBuffer(); + this.closed = true; + } + + + public void setOption(String key, String value) + { + super.setOption(key, value); + + if (key.equalsIgnoreCase(URL_OPTION)) + databaseURL = value; + else if (key.equalsIgnoreCase(USER_OPTION)) + databaseUser = value; + else if (key.equalsIgnoreCase(PASSWORD_OPTION)) + databasePassword = value; + else if (key.equalsIgnoreCase(BUFFER_OPTION)) + bufferSize = Integer.parseInt(value); + } + + + /** + * Override this to create the SQL needed for your DB schema + */ + protected String getSQL(LoggingEvent event) + { + String msg = this.layout.format(event); + String sql = "spLog '" + msg + "'"; + System.out.println(sql); //DEBUG + return sql; + } + + /** + * Override this to provide an alertnate method of getting connections (such as caching) + * This implementation creates a new connection and statement for every execution which + * is very wastefull. One method to fix this is to open connections at the start of + * flushBuffer() and close them at the end. MD Data uses a connection pool outside + * of JDBCAppender which is accessed in the override of this method. + */ + protected void executeSQL(String sql) throws SQLException + { + Connection con = null; + Statement stmt = null; + + + try { + con = DriverManager.getConnection(databaseURL, databaseUser, databasePassword); + stmt = con.createStatement(); + stmt.executeUpdate(sql); + } + catch (SQLException e) + { + if (con != null) + con.close(); + if (stmt != null) + stmt.close(); + + throw e; + } + stmt.close(); + con.close(); + } + + public void flushBuffer() + { + //Do the actual logging + for (Iterator i = buffer.iterator(); i.hasNext();) + { + try { + String sql = getSQL((LoggingEvent)i.next()); + executeSQL(sql); + } + catch (SQLException e) + { + errorHandler.error("Failed to excute sql", e, ErrorCode.FLUSH_FAILURE); + } + } + buffer.clear(); + } + + public void finalize() + { + close(); + } + + public boolean requiresLayout() + { + return true; + } + + +}package org.apache.log4j.varia.test; + + +import org.apache.log4j.varia.JDBCAppender; +import org.apache.log4j.*; + + +public class JDBCTest +{ + public static void main (String argv[]) + { + try { + Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); + } + catch (Exception e) + { + e.printStackTrace(); + System.out.println(e.toString()); + } + + Category rootLog = Category.getRoot(); + Layout layout = new PatternLayout("%p [%t] %c - %m%n"); + JDBCAppender appender = new JDBCAppender(); + appender.setLayout(layout); + appender.setOption(JDBCAppender.URL_OPTION, "jdbc:odbc:someDB"); + appender.setOption(JDBCAppender.USER_OPTION, "auser"); + appender.setOption(JDBCAppender.PASSWORD_OPTION, "thepassword"); + + rootLog.addAppender(appender); + + + try { + Category log = Category.getInstance("main"); + log.debug("Debug 1"); + Thread.sleep(500); + log.info("info 1"); + Thread.sleep(500); + log.warn("warn 1"); + Thread.sleep(500); + log.error("error 1"); + Thread.sleep(500); + log.fatal("fatal 1"); + Thread.sleep(500); + + appender.setOption(JDBCAppender.BUFFER_OPTION, "5"); + log.debug("Debug 2"); + Thread.sleep(500); + log.info("info 2"); + Thread.sleep(500); + log.warn("warn 2"); + Thread.sleep(500); + log.error("error 2"); + Thread.sleep(500); + log.fatal("fatal 2"); + Thread.sleep(500); + + + appender.setOption(JDBCAppender.BUFFER_OPTION, "2"); + appender.setThreshold(Priority.WARN); + log.debug("Debug 3"); + Thread.sleep(500); + log.info("info 3"); + Thread.sleep(500); + log.warn("warn 3"); + Thread.sleep(500); + log.error("error 3"); + Thread.sleep(500); + log.fatal("fatal 3"); + } + catch (InterruptedException e) + { + System.out.println("Interrupted"); + } + } +} diff --git a/contribs/KevinSteppe/mail-2002-03-27.txt b/contribs/KevinSteppe/mail-2002-03-27.txt new file mode 100644 index 0000000000..52e93e59f5 --- /dev/null +++ b/contribs/KevinSteppe/mail-2002-03-27.txt @@ -0,0 +1,118 @@ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +Received: (qmail 12476 invoked from network); 28 Mar 2002 06:19:49 -0000 +Date: Wed, 27 Mar 2002 22:28:58 -0800 +From: Kevin Steppe +Subject: Re: RollingFileAppender and DailyRollingFileAppender +To: Log4J Users List +Reply-To: ksteppe@pacbell.net +Message-id: <3CA2B82A.5C366593@pacbell.net> +MIME-version: 1.0 +X-Mailer: Mozilla 4.7 [en] (WinNT; I) +Content-type: multipart/mixed; boundary="Boundary_(ID_TnKsnil+d0oYB9TV0P+fgA)" +X-Accept-Language: en +References: + <8DAB344CC3F3FE42A51FA1A8E295F8682ACD14@tepg-server2.tepgsyd.tycoint.com.au> +X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N + +I wrote a CompositeRollingAppender last August to do that. I'm attaching that +code and some example config files to you separately. + +Ceki... Could you please put these files in the log4j/contribs/KevinSteppe +folder of the available releases? This seems to be coming up occasionally and +it would be more convenient to just point people there. + +Thanks, +Kevin + + +Janusz Dalecki wrote: + +> Is there a way of having the mixture of both RollingFileAppender and +> DailyRollingFileAppender options?. I have a requirement to log daily and +> delete old files weekly. +> Thanks, +> Janusz +> +> -- +> To unsubscribe, e-mail: +> For additional commands, e-mail: + +#Config file for CompositeRollingAppender +#This is an example config to use CompositeRollingAppender in Size based Backups only + +log4j.rootCategory=debug, R +log4j.appender.R=org.apache.log4j.CompositeRollingAppender + +#How to perform rolling -- 1 = By Size +#Note -- this is the only difference from RollingFileAppender! +log4j.appender.R.RollingStyle=1 + +#file to log to +log4j.appender.R.File=example.log + +#Size Rolling params +log4j.appender.R.MaxFileSize=10MB +log4j.appender.R.MaxSizeRollBackups=10 + +#layout options +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n +#Config file for CompositeRollingAppender +#This is an example config to use CompositeRollingAppender in Time based Backups only + +log4j.rootCategory=debug, R +log4j.appender.R=org.apache.log4j.CompositeRollingAppender + +#How to perform rolling -- 2 = By Time +#Note -- this is the only difference from DailyRollingFileAppender! +log4j.appender.R.RollingStyle=2 + +#file to log to +log4j.appender.R.File=example.log + +#Date Rolling params +log4j.appender.R.datePattern='.'yyyy-MM-dd + +#layout options +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n +#Default Config file for CompositeRollingAppender +log4j.rootCategory=debug, R + +log4j.appender.R=org.apache.log4j.CompositeRollingAppender + +#How to perform rolling -- Composite is the default +log4j.appender.R.RollingStyle=3 + +#Use same file name for all inprocess logging? +log4j.appender.R.staticLogFileName=true +log4j.appender.R.File=example.log + +#Size Rolling params +log4j.appender.R.CountDirection=-1 +log4j.appender.R.MaxFileSize=5KB +log4j.appender.R.MaxSizeRollBackups=10 + +#Date Rolling params +log4j.appender.R.datePattern='.'yyyy-MM-dd + +#layout options +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n + diff --git a/contribs/KitchingSimon/DatagramStringAppender.java b/contribs/KitchingSimon/DatagramStringAppender.java new file mode 100644 index 0000000000..f718580880 --- /dev/null +++ b/contribs/KitchingSimon/DatagramStringAppender.java @@ -0,0 +1,284 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.net; + +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.DatagramPacket; +import java.net.UnknownHostException; +import java.net.SocketException; + +import org.apache.log4j.helpers.OptionConverter; +import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.Category; +import org.apache.log4j.Priority; +import org.apache.log4j.Layout; + +import org.apache.log4j.helpers.SingleLineTracerPrintWriter; +import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.helpers.QuietWriter; + + +/** + Use DatagramStringAppender to send log messages to a remote daemon + which accepts Datagram (UDP) messages. +

+ The benefits of UDP are that the client is guarunteed not to + slow down if the network or remote log daemon is slow, and that + no permanent TCP connection between client and server exists. +

+ The disadvantages are that log messages can be lost if the network + or remote daemon are under excessive load. +

+ This class builts the final message string before sending + the UDP packet, hence the "string" component in the class name. This + means that the receiving application can be written in any language. + The data is transmitted in whatever encoding is specified in the + configuration file; this may be an 8-bit encoding (eg ISO-8859-1, also + known as LATIN-1) or a larger encoding, eg UTF-16. +

+ An alternative to building the message string within DatagramStringAppender + would be to serialize & send the complete logging event object (perhaps + such a class could be called a DatagramSerialAppender??). The + receiving end could then be configured with appropriate Layout objects + to generate the actual logged messages. This would ensure that the + logging of messages from different sources is done in a consistent + format, and give a central place to configure that format. It would ensure + (by transmitting messages as unicode) that the receiving end could control + the encoding in which the output is generated. It also would possibly allow + he receiving end to use the full log4j flexibility to pass the event to + different appenders at the receiving end, as the category information is + retained, etc. However, this does require that the receiving end is in + java, and that all clients of the logging daemon are java applications. + In contrast, this DatagramStringAppender can send mesages to a log daemon + that accepts messages from a variety of sources. + + @author Simon Kitching + */ +public class DatagramStringAppender extends AppenderSkeleton { + + /** + A string constant used in naming the option for setting the destination + server for messages. Current value of this string constant is + DatagramHost. */ + public static final String DATAGRAM_HOST_OPTION = "DatagramHost"; + + /** + A string constant used in naming the option for setting the destination + port for messages. Current value of this string constant is + DatagramPort. */ + public static final String DATAGRAM_PORT_OPTION = "DatagramPort"; + + /** + A string constant used in naming the option for setting the character + encoding used when generating the log message. Current value of this + string constant is DatagramEncoding. */ + public static final String DATAGRAM_ENCODING_OPTION = "DatagramEncoding"; + + /** + The default value for the "host" attribute, ie the machine to which + messages are sent. Current value of this string constant is + localhost. */ + public static final String DEFAULT_HOST = "localhost"; + + /** + The default value for the "port" attribute, ie the UDP port to which + messages are sent. Current value of this integer constant is + 8200. This value was chosen for no particular reason. */ + public static final int DEFAULT_PORT = 8200; + + /** + The default value for the "encoding" attribute, ie the way in which + unicode message strings are converted into a stream of bytes before + their transmission as a UDP packet. The current value of this constant + is null, which means that the default platform encoding will + be used. */ + public static final String DEFAULT_ENCODING = null; + + String host = DEFAULT_HOST; + int port = DEFAULT_PORT; + String encoding = DEFAULT_ENCODING; + + SingleLineTracerPrintWriter stp; + QuietWriter qw; + + public + DatagramStringAppender() { + this.setDestination(DEFAULT_HOST, DEFAULT_PORT, DEFAULT_ENCODING); + } + + public + DatagramStringAppender(Layout layout) { + this.setLayout(layout); + this.setDestination(DEFAULT_HOST, DEFAULT_PORT, DEFAULT_ENCODING); + } + + public + DatagramStringAppender(Layout layout, String host, int port) { + this.setLayout(layout); + this.setDestination(host, port, DEFAULT_ENCODING); + } + + public + DatagramStringAppender(Layout layout, String host, int port, String encoding) { + this.setLayout(layout); + this.setDestination(host, port, encoding); + } + + /** + Release any resources held by this Appender + */ + public + void close() { + closed = true; + // A DatagramWriter is UDP based and needs no opening. Hence, it + // can't be closed. We just unset the variables here. + qw = null; + stp = null; + } + + public + void append(LoggingEvent event) { + if(!isAsSevereAsThreshold(event.priority)) + return; + + // We must not attempt to append if qw is null. + if(qw == null) { + errorHandler.error( + "No host is set for DatagramStringAppender named \"" + + this.name + "\"."); + return; + } + + String buffer = layout.format(event); + qw.write(buffer); + + if(event.throwable != null) + event.throwable.printStackTrace(stp); + else if (event.throwableInformation != null) { + // we must be the receiver of a serialized/deserialized LoggingEvent; + // the event's throwable member is transient, ie becomes null when + // deserialized, but that's ok because throwableInformation should + // have the string equivalent of the same info (ie stack trace) + qw.write(event.throwableInformation); + } + } + + /** + Activate the options set via the setOption method. + + @see #setOption + */ + public + void activateOptions() { + this.setDestination(this.host, this.port, this.encoding); + } + + /** + Returns the option names for this component, namely the string + array consisting of {{@link #DATAGRAM_HOST_OPTION}, {@link + #DATAGRAM_PORT_OPTION}, {@link #DATAGRAM_ENCODING_OPTION} */ + public + String[] getOptionStrings() { + return OptionConverter.concatanateArrays(super.getOptionStrings(), + new String[] { + DATAGRAM_HOST_OPTION, + DATAGRAM_PORT_OPTION, + DATAGRAM_ENCODING_OPTION}); + } + + /** + The DatagramStringAppender requires a layout. Hence, this method return + true. + + @since 0.8.4 */ + public + boolean requiresLayout() { + return true; + } + + /** + Set DatagramStringAppender specific parameters. +

+ The recognized options are DatagramHost, DatagramPort and + DatagramEncoding, i.e. the values of the string constants + {@link #DATAGRAM_HOST_OPTION}, {@link #DATAGRAM_PORT_OPTION} and + {@link #DATAGRAM_ENCODING_OPTION} respectively. +

+

+

+

DatagramHost +
+ The name (or ip address) of the host machine where log output should go. + If the DatagramHost is not set, then this appender will default to + {@link #DEFAULT_HOST}. +

+

DatagramPort +
+ The UDP port number where log output should go. See {@link #DEFAULT_PORT} +

+

DatagramEncoding +
+ The ISO character encoding to be used when converting the Unicode + message to a sequence of bytes within a UDP packet. If not defined, then + the encoding defaults to the default platform encoding. +
+ */ + public + void setOption(String option, String value) { + if(value == null) return; + + super.setOption(option, value); + + if(option.equals(DATAGRAM_HOST_OPTION)) + { + this.host = value; + } + else if(option.equals(DATAGRAM_PORT_OPTION)) + { + this.port = OptionConverter.toInt(value, DEFAULT_PORT); + } + else if(option.equals(DATAGRAM_ENCODING_OPTION)) + { + this.encoding = value; + } + } + + public + void setDestination(String host, int port, String encoding) { + if (host==null) { + LogLog.error("setDestination: host is null"); + host = DEFAULT_HOST; + } + + this.host = host; + this.port = port; + this.encoding = encoding; + + this.qw = new QuietWriter( + new DatagramStringWriter(host, port, encoding), + errorHandler); + this.stp = new SingleLineTracerPrintWriter(qw); + } + + public + void setLayout(Layout layout) { + this.layout = layout; + } +} diff --git a/contribs/KitchingSimon/DatagramStringWriter.java b/contribs/KitchingSimon/DatagramStringWriter.java new file mode 100644 index 0000000000..0120863999 --- /dev/null +++ b/contribs/KitchingSimon/DatagramStringWriter.java @@ -0,0 +1,173 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.net; + +import java.io.Writer; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.DatagramPacket; +import java.net.UnknownHostException; +import java.net.SocketException; +import java.io.IOException; + +import org.apache.log4j.helpers.LogLog; + +/** + * DatagramStringWriter is a wrapper around the java.net.DatagramSocket class + * so that it behaves like a java.io.Writer. + */ +public class DatagramStringWriter extends Writer { + + static final int SYSLOG_PORT = 514; + + private int port; + private String host; + private String encoding; + private String prefix; + + private InetAddress address; + private DatagramSocket ds; + + /** + * This constructor assumes that it is sending to a remote syslog daemon + * on the normal syslog port (514), and uses the default platform character + * encoding when converting the message string to a byte sequence. + */ + public + DatagramStringWriter(String host) { + this(host, SYSLOG_PORT, null, null); + } + + /** + * This constructor sends messages to the specified host and port, and + * uses the default platform character encoding when converting the message + * string to a byte sequence. + */ + public + DatagramStringWriter(String host, int port) { + this(host, port, null, null); + } + + /** + * This constructor sends messages to the specified host and port, and + * uses the specified character encoding when converting the message + * string to a byte sequence. + */ + public + DatagramStringWriter(String host, int port, String encoding) { + this(host, port, null, null); + } + /** + * This constructor sends messages to the specified host and port, and + * uses the specified character encoding when converting the message + * string to a byte sequence; the specified prefix (which may be null) + * is prepended to each message. + */ + public + DatagramStringWriter(String host, int port, String encoding, String prefix) { + this.host = host; + this.port = port; + this.encoding = encoding; + this.prefix = prefix; + + try { + this.address = InetAddress.getByName(host); + } + catch (UnknownHostException e) { + LogLog.error("Could not find " + host + + ". All logging will FAIL.", e); + } + + try { + this.ds = new DatagramSocket(); + } + catch (SocketException e) { + e.printStackTrace(); + LogLog.error("Could not instantiate DatagramSocket to " + host + + ". All logging will FAIL.", e); + } + } + + + public + void write(char[] buf, int off, int len) throws IOException { + this.write(new String(buf, off, len)); + } + + public + void write(String string) throws IOException { + if (prefix != null) { + string = prefix + string; + } + + byte[] rawData; + if (this.encoding == null) + { + // convert to byte sequence using platform's default encoding + rawData = string.getBytes(); + } + else + { + // convert to specified encoding - which may be sequence of + // 8-bit chars, or multi-byte encodings like UTF-8 or UTF-16. + // The receiving end had better be expecting whatever encoding + // is used here on the sending end! + rawData = string.getBytes(encoding); + } + + DatagramPacket packet = + new DatagramPacket( + rawData, + rawData.length, + address, + port); + + if(this.ds != null) + { + ds.send(packet); + } + else + { + LogLog.error( + "write: failed to create DatagramPacket"); + } + } + + public + void flush() {} + + public + void close() {} + + /** + * Set a string to be prefixed to every message sent by this Writer. + * For example, this method could be used to prepend a syslog + * facility/priority code on the front of each message. + *

+ * Note that this method is not synchronised, so should not be called in + * a situation where other threads may be logging messages at the same + * moment. + *

+ * @param prefix may be a prefix string, or null which indicates no + * prefix should be added. + */ + public + void setPrefix(String prefix){ + this.prefix = prefix; + } +} diff --git a/contribs/KitchingSimon/SingleLineTracerPrintWriter.java b/contribs/KitchingSimon/SingleLineTracerPrintWriter.java new file mode 100644 index 0000000000..50f8da24d1 --- /dev/null +++ b/contribs/KitchingSimon/SingleLineTracerPrintWriter.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.helpers; + +/** + SingleLineTracerPrintWriter overrides the println function in + TracerPrintWriter by replacing the TAB character with spaces. + It also does not print the "\n". +

+ The default format generated by TracerPrintWriter for exceptions + prints on multiple lines, which does not interact well with some + logging systems. On the other hand, a stack-trace on one line can be a + mite difficult to read, so this class should only be used where really + necessary :-) +

+ For syslog daemons, tabs in messages are not friendly, hence the + replacement of tabs by spaces here. It shouldn't do any harm to + do this for all messages... +

+ Perhaps it might be better to enhance TracerPrintWriter to have + a configuration item for one-line or multi-line mode... +*/ +public class SingleLineTracerPrintWriter extends TracerPrintWriter { + + static String TAB = " "; + + public SingleLineTracerPrintWriter(QuietWriter qWriter) { + super(qWriter); + } + + /** + Make the first Exception line print properly by omitting the \n at the + end. + */ + public + void println(Object o) { + this.qWriter.write(o.toString()); + } + + // Note: the Char[] form is handled by the TracerPrinterWriter super + // class + + /** + Remove the first character from the string (usually a TAB) and do + not print "\n" + */ + public + void println(String s) { + // remove '^I' and replace it with 4 spaces + this.qWriter.write(TAB+s.substring(1)); + } +} diff --git a/contribs/KitchingSimon/logconfig.xml b/contribs/KitchingSimon/logconfig.xml new file mode 100644 index 0000000000..9ff8c09702 --- /dev/null +++ b/contribs/KitchingSimon/logconfig.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contribs/KitchingSimon/mail-2001-02-07 b/contribs/KitchingSimon/mail-2001-02-07 new file mode 100644 index 0000000000..143e2930e2 --- /dev/null +++ b/contribs/KitchingSimon/mail-2001-02-07 @@ -0,0 +1,107 @@ + + + +Delivered-To: urba-cgu@urbanet.ch +Mailing-List: contact log4j-dev-help@jakarta.apache.org; run by ezmlm +List-Post: +List-Help: +List-Unsubscribe: +List-Subscribe: +Reply-To: "LOG4J Developers Mailing List" +Delivered-To: mailing list log4j-dev@jakarta.apache.org +From: Kitching Simon +To: "'log4j-dev@jakarta.apache.org'" +Subject: PATCH: New classes: DatagramStreamAppender & friends +Date: Wed, 7 Feb 2001 12:41:54 +0100 +X-Mailer: Internet Mail Service (5.5.2650.21) +X-Spam-Rating: h31.sny.collab.net 1.6.2 0/1000/N + + +Hi log4j developers.... + + +Here, for your consideration, is a set of files that +implement an Appender which sends messages +to a remote host/port via UDP (datagram). + + +There was brief discussion of this Appender on the +log4j-user group, about a week ago. Ceki suggested +that the Appender send serialized log event objects +over UDP; while this approach has a number of +advantages, I have decided to instead perform the +message formatting at the client end, mainly so +that: +(a) the UDP server application does not have to be in java +(b) non-java clients can send messages to the same UDP + server. + + +The appender has been named "DatagramStringAppender" +to allow someone to write a serialization-based version at +some later time, if desired, without any name confusion. +------------------------------ +Notes: + + +DatagramStringAppender is based on SyslogAppender, but +with a fair number of changes. + + +DatagramStringWriter is based on SyslogWriter, with a few changes. +In particular, it takes an "encoding" parameter, so that the character +encoding used can be specified, and a "port". + + +SingleLineTracerPrintWriter is almost identical to +SyslogTracerPrintWriter; just the name & some comments +have changed. [I didn't want to call a class called SyslogXXX +from the DatagramStreamAppender classes] +------------------------------ + + +If this patch is accepted, then it may be worth rewriting SyslogAppender +to use the DatagramStringWriter and SingleLineTracerPrintWriter +classes. These classes should be compatible with SyslogAppender, +as they implement the same functionality, or a superset of the +Syslog functionality, and have more "general" names. +------------------------------ + <> + + + + <> + + + <> + + +-------------------------------- +And here's a simple perl UDP server, and an xml +config file for testing the appender. + <> + + + <> + + +Regards, + + +Simon diff --git a/contribs/KitchingSimon/udpserver.pl b/contribs/KitchingSimon/udpserver.pl new file mode 100644 index 0000000000..be13d9cbe8 --- /dev/null +++ b/contribs/KitchingSimon/udpserver.pl @@ -0,0 +1,82 @@ +#!/opt/perl5/bin/perl -w +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +use strict; +use Socket; +use IO::Socket; +use Sys::Hostname; + +main(); +exit(0); + +sub main() +{ + my $MAX_MSG_SIZE = 16384; # 16KBytes should be enough... + + my $svrport = 8300; + my $svriaddr = gethostbyname(hostname()); + my $svrproto = getprotobyname('udp'); + my $svrpaddr = sockaddr_in($svrport, $svriaddr); + + socket(SOCKET, PF_INET, SOCK_DGRAM, $svrproto) || die "socket: $!"; + bind(SOCKET, $svrpaddr) || die "bind: $!"; + + my $rin = ''; + vec($rin, fileno(SOCKET), 1) = 1; + + # timeout after 10.0 seconds + # at some time, I'm going to add signal handlers so that signals can be + # sent to cause logfile rollover, or tidy exit...then the timeout will + # come in useful.. + + my $exit = 0; + while (!$exit) + { + my $rout = $rin; + + # select(readvec, writevec, exceptionvec, timeout) + # : returns # of selected filehandles, modifies + # vector parameters so that set bits indicate + # filehandles which are readable, writable or have + # an exception state + + my $nSelected = select($rout, undef, undef, 10.0); + if ($nSelected == 0) + { + # timedout : go back to start of loop + next; + } + + my $msgData = ''; + my $clientpaddr = recv(SOCKET, $msgData, $MAX_MSG_SIZE, 0); + if (!$clientpaddr) + { + die "recv: $!"; + } + + my ($clientport, $clientiaddr) = sockaddr_in($clientpaddr); + my $clienthost = gethostbyaddr($clientiaddr, AF_INET); + if (!$clienthost) + { + # unable to determine name for client : show raw ip address + $clienthost = inet_ntoa($clientiaddr); + } + + print "$clienthost:$msgData\n"; + } +} + + diff --git a/contribs/LeosLiterak/TempFileAppender.java b/contribs/LeosLiterak/TempFileAppender.java new file mode 100644 index 0000000000..0d8562a4af --- /dev/null +++ b/contribs/LeosLiterak/TempFileAppender.java @@ -0,0 +1,198 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.apache.log4j; + +import java.io.File; +import java.io.Writer; +import java.io.FileWriter; +import java.io.BufferedWriter; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.helpers.OptionConverter; +import org.apache.log4j.spi.ErrorHandler; + +/** + TempFileAppender creates new unique file for each logging statement. + + @author Leos Literak + @author Ceki Gülcü + +*/ +public class TempFileAppender extends AppenderSkeleton { + + /** + A string constant used in naming the option for setting the + directory where the log files will be created. Current value + of this string constant is Path. java.io.tmpdir directory + will be used, if ommited. + */ + static final public String PATH_OPTION = "Path"; + + /** + The default path is actual directory. + */ + protected String path = null; + + /** + A string constant used in naming the option for setting the + prefix of the log files. It has to have at least 3 characters! + Current value of this string constant is Prefix. + */ + static final public String PREFIX_OPTION = "Prefix"; + + /** + The default path is actual directory. + */ + protected String prefix = "l4j_"; + + /** + A string constant used in naming the option for setting the + suffix of the log files. Current value of this string constant + is Suffix. + */ + static final public String SUFFIX_OPTION = "Suffix"; + + /** + The default path is actual directory. + */ + protected String suffix = ".tmp"; + + /** + Default dir + */ + + protected File dir = null; + + + + + /** + The default constructor simply calls its parent's constructor. + */ + public TempFileAppender() { + super(); + } + + /** + Retuns the option names for this component + */ + public String[] getOptionStrings() { + return OptionConverter.concatanateArrays(super.getOptionStrings(), + new String[] {PATH_OPTION,PREFIX_OPTION,SUFFIX_OPTION}); + } + + /** + Set TempFileAppender specific options. + + The recognized options are Path, Prefix and Suffix, + i.e. the values of the string constants {@link #PATH_OPTION}, + {@link #PREFIX_OPTION} and respectively {@link #SUFFIX_OPTION}. + The options of the super class {@link AppenderSkeleton} are also + recognized. + */ + + public void setOption(String key, String value) { + super.setOption(key, value); + if(key.equalsIgnoreCase(PATH_OPTION)) { + path = value; + if(path==null) { + errorHandler.error("Path cannot be empty!",null,0); + } + + dir = new File(path); + if(!(dir.exists() && dir.isDirectory() && dir.canWrite())) { + errorHandler.error("Cannot write to directory " + path + "!",null,0); + } + } + else if(key.equalsIgnoreCase(PREFIX_OPTION)) { + if(value!=null && value.length()>=3) { + prefix = value; + } else { + errorHandler.error("Prefix cannot be shorter than 3 characters!", + null,0); + } + } + else if(key.equalsIgnoreCase(SUFFIX_OPTION)) { + if(value!=null && value.length()>=1) { + suffix = value; + } else { + errorHandler.error("Suffix cannot be empty!",null,0); + } + } + } + + /** + This method is called by {@link AppenderSkeleton#doAppend} + method. + +

Whenever this method is called, new unique file is created + with specified prefix and suffix. The file is closed afterwards. + +

The format of the output will depend on this appender's + layout. + + */ + public void append(LoggingEvent event) { + if(!checkEntryConditions()) { + return; + } + subAppend(event); + } + + /** + This method determines if there is a sense in attempting to append. + */ + protected boolean checkEntryConditions() { + return true; + } + + /** + This method does actual writing + */ + protected void subAppend(LoggingEvent event) { + try { + File tmp = File.createTempFile(prefix,suffix,dir); + Writer out = new BufferedWriter(new FileWriter(tmp)); + out.write(event.message); + out.close(); + /* this Appender is not supposed to be used for logging of Exceptions */ + } catch (Exception e) { + errorHandler.error("Error during creation of temporary File!",e,1); + } + } + + public boolean requiresLayout() { + return false; + } + + public void close() { + /* nothing to do */ + } +} +/* + * @author $Author$ + * @version $Revision$ + * @since $Date$ + * + * $Log$ + * Revision 1.1.2.1 2005/05/27 03:27:54 mwomack + * Fix for #35032. Added license header to .java files that did not already have a license. + * + * Revision 1.1 2001/04/20 17:38:31 ceki + * + * Added LeosLiterak's TempFileAppender.java + * +*/ diff --git a/contribs/LeosLiterak/mail b/contribs/LeosLiterak/mail new file mode 100644 index 0000000000..0a617f925e --- /dev/null +++ b/contribs/LeosLiterak/mail @@ -0,0 +1,58 @@ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +To: ceki@apache.org +Subject: TempFileAppender + + +Hi Ceki, + + +I have created one small Appender, which puts each +logging statement into separate file. We use it +for storing incomming messages into second process'es +spool directory. If you like it, please include it +into Log4j with APL license. + + +Usage: + + +log4j.appender.A1=org.apache.log4j.TempFileAppender +log4j.appender.A1.Path=spool_dir +log4j.appender.A1.Prefix=out_ +log4j.appender.A1.Suffix=.msg + + + Leo + +----------------------------------------------------- +Leos Literak +Software Engineer + + +12snap s.r.o. +Pstrossova 24 +110 00 Praha 1 +Czech Republic + + +mobile: ?605-849-087 +phone: ?2-21-970-239 +fax: ?2-21-970-241 +e-mail: leos.literak@12snap.com + diff --git a/contribs/MarkDouglas/Log.txt b/contribs/MarkDouglas/Log.txt new file mode 100644 index 0000000000..d50d537a0e --- /dev/null +++ b/contribs/MarkDouglas/Log.txt @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +INFO ( Server:main ) systemsunion.LoggingServer.SocketServer2 - Connected to client at RDDSOWE2/129.153.78.195 +INFO ( Server:main ) systemsunion.LoggingServer.SocketServer2 - Starting new socket node. +INFO ( Server:main ) systemsunion.LoggingServer.SocketServer2 - Waiting to accept a new client. +INFO ( RDDSOWE2:main ) systemsunion.SSTS.system - ClosedownController: starting +INFO ( Server:main ) systemsunion.LoggingServer.SocketServer2 - Connected to client at RDDSOWE2/129.153.78.195 +INFO ( Server:main ) systemsunion.LoggingServer.SocketServer2 - Starting new socket node. +INFO ( Server:main ) systemsunion.LoggingServer.SocketServer2 - Waiting to accept a new client. +INFO ( RDDSOWE2:main ) systemsunion.SSTS.system - ClosedownController: starting +INFO ( RDDSOWE2:AWT-EventQueue-0) systemsunion.SSTS.components - Packing component Operator +INFO ( RDDSOWE2:AWT-EventQueue-0) systemsunion.SSTS.components - Packing class file d:/SSDev/SSTS/components\Operator\Operator.class for component Operator +INFO ( RDDSOWE2:AWT-EventQueue-0) systemsunion.SSTS.components - Packing class file d:/SSDev/SSTS/components\Operator\Operator.class for component Operator +INFO ( RDDSOWE2:AWT-EventQueue-0) systemsunion.SSTS.components - Packing proxy class file d:/SSDev/SSTS/components\Operator\OperatorProxy.class for component Operator +INFO ( RDDSOWE2:AWT-EventQueue-0) systemsunion.SSTS.components - Packing class file d:/SSDev/SSTS/components\Operator\OperatorProxy.class for component Operator +INFO ( RDDSOWE2:AWT-EventQueue-0) systemsunion.SSTS.components - Packing test XML page file d:/SSDev/SSTS/components\Operator\Operator.XML for component Operator +INFO ( RDDSOWE2:AWT-EventQueue-0) systemsunion.SSTS.components - Packing class file d:/SSDev/SSTS/components\Operator\Operator.XML for component Operator +INFO ( RDDSOWE2:AWT-EventQueue-0) systemsunion.SSTS.components - Packing descriptor file d:/SSDev/SSTS/components\Operator\OperatorDeploymentDescriptor.XML for component Operator +INFO ( RDDSOWE2:AWT-EventQueue-0) systemsunion.SSTS.components - Packing class file d:/SSDev/SSTS/components\Operator\OperatorDeploymentDescriptor.XML for component Operator diff --git a/contribs/MarkDouglas/SocketNode2.java b/contribs/MarkDouglas/SocketNode2.java new file mode 100644 index 0000000000..60f63e755f --- /dev/null +++ b/contribs/MarkDouglas/SocketNode2.java @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.systemsunion.LoggingServer; + +import java.net.InetAddress; +import java.net.Socket; +import java.net.ServerSocket; +import java.io.InputStream; +import java.io.IOException; +import java.io.ObjectInputStream; + + +import org.apache.log4j.Category; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.Priority; +import org.apache.log4j.NDC; + +// Contributors: Moses Hohman + +/** + Read {@link LoggingEvent} objects sent from a remote client using + Sockets (TCP). These logging events are logged according to local + policy, as if they were generated locally. + +

For example, the socket node might decide to log events to a + local file and also resent them to a second socket node. + + @author Ceki Gülcü + + @since 0.8.4 +*/ +public class SocketNode2 implements Runnable { + + Socket socket; + ObjectInputStream ois; + + static Category cat = Category.getInstance(SocketNode2.class.getName()); + + public + SocketNode2(Socket socket) { + this.socket = socket; + try { + ois = new ObjectInputStream(socket.getInputStream()); + } + catch(Exception e) { + cat.error("Could not open ObjectInputStream to "+socket, e); + } + } + + //public + //void finalize() { + //System.err.println("-------------------------Finalize called"); + // System.err.flush(); + //} + + public void run() { + LoggingEvent event; + Category remoteCategory; + String strClientName; + + // Get the client name. + InetAddress addr = socket.getInetAddress(); + strClientName = addr.getHostName(); + if(strClientName == null || strClientName.length() == 0) + { + strClientName = addr.getHostAddress(); + } + + try { + while(true) { + event = (LoggingEvent) ois.readObject(); + + if(event.ndc != null) + { + event.ndc = strClientName + ":" + event.ndc; + } + else + { + event.ndc = strClientName; + } + + remoteCategory = Category.getInstance(event.categoryName); + remoteCategory.callAppenders(event); + } + } + catch(java.io.EOFException e) { + cat.info("Caught java.io.EOFException will close conneciton.", e); + } + catch(java.net.SocketException e) { + cat.info("Caught java.net.SocketException, will close conneciton.", e); + } + catch(Exception e) { + cat.error("Unexpected exception. Closing conneciton.", e); + } + + try { + ois.close(); + } + catch(Exception e) { + cat.info("Could not close connection.", e); + } + } +} diff --git a/contribs/MarkDouglas/SocketServer2.java b/contribs/MarkDouglas/SocketServer2.java new file mode 100644 index 0000000000..96caf0ea26 --- /dev/null +++ b/contribs/MarkDouglas/SocketServer2.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.systemsunion.LoggingServer; + +import java.net.Socket; +import java.net.ServerSocket; +import java.io.IOException; + +import org.apache.log4j.Category; +import org.apache.log4j.PropertyConfigurator; +import org.apache.log4j.NDC; + +/** + A simple {@link SocketNode} based server. + +

+	 Usage: java org.apache.log4j.net.SocketServer port configFile
+
+	 where port is a part number where the server listens and
+	 configFile is a configuration file fed to the {@link
+	 PropertyConfigurator}.
+   
+ + + + + + @author Ceki Gülcü + + @since 0.8.4 */ + +public class SocketServer2 { + + static Category cat = Category.getInstance(SocketServer2.class.getName()); + + static int port; + + public + static + void main(String argv[]) { + if(argv.length == 2) + init(argv[0], argv[1]); + else + usage("Wrong number of arguments."); + + try { + cat.info("Listening on port " + port); + ServerSocket serverSocket = new ServerSocket(port); + while(true) { + cat.info("Waiting to accept a new client."); + Socket socket = serverSocket.accept(); + cat.info("Connected to client at " + socket.getInetAddress()); + cat.info("Starting new socket node."); + new Thread(new SocketNode2(socket)).start(); + } + } + catch(Exception e) { + e.printStackTrace(); + } + } + + + static + void usage(String msg) { + System.err.println(msg); + System.err.println( + "Usage: java " + SocketServer2.class.getName() + " port configFile"); + System.exit(1); + } + + static + void init(String portStr, String configFile) { + try { + port = Integer.parseInt(portStr); + } + catch(java.lang.NumberFormatException e) { + e.printStackTrace(); + usage("Could not interpret port number ["+ portStr +"]."); + } + PropertyConfigurator.configure(configFile); + NDC.push("Server"); + } +} diff --git a/contribs/MarkDouglas/mail-2001-01-17 b/contribs/MarkDouglas/mail-2001-01-17 new file mode 100644 index 0000000000..65cd8cd684 --- /dev/null +++ b/contribs/MarkDouglas/mail-2001-01-17 @@ -0,0 +1,66 @@ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +Delivered-To: urba-cgu@urbanet.ch +From: Mark Douglas +To: "'cgu@urbanet.ch'" +Subject: Enhanced SocketServer and SocketNode classes +Date: Wed, 17 Jan 2001 09:57:38 -0000 +X-Mailer: Internet Mail Service (5.5.2650.21) + + +Hi Ceki, + + +I have made small changes to SocketServer and SockerNode to allow the client +machine name to be displayed in the logging output. This is important for +us as we are using a single logging server with several clients. + + +The new SocketServer2 and SocketNode2 classes (couldn't think of better +names) prepends the NDC string with the clients Host Name (or IP address if +the HostName can not be found). I thought the NDC string was a good place +to add this information, but you may have a better place? + + +I have created an NDC entry for the server such that server logging messages +can easily be identified. + + +I have included the two new source files plus a short example of the output. + + +The output was generated with the following layout: %-6p (%9x:%-10t) +%-40c{3} - %m%n + + + <> <> <> + + +Note: I have changed the package names for the two classes to fit with our +package names - sorry. Also, I find it difficult to follow the coding +style, so again, sorry. + + +If you think this may be useful to others, please feel free to include it as +an addition in the next release or change the current SocketServer and +SocketNode objects to include this new behaviour by default. + + +Mark Douglas +Systems Union Group plc + + diff --git a/contribs/SvenReimers/gui/JListView.java b/contribs/SvenReimers/gui/JListView.java new file mode 100644 index 0000000000..6a93ed08e6 --- /dev/null +++ b/contribs/SvenReimers/gui/JListView.java @@ -0,0 +1,365 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.log4j.gui; + +import org.apache.log4j.helpers.CyclicBuffer; +import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.Priority; +import org.apache.log4j.Category; +import org.apache.log4j.Layout; +import org.apache.log4j.PatternLayout; +import org.apache.log4j.spi.LoggingEvent; + +import javax.swing.JList; +import javax.swing.AbstractListModel; +import javax.swing.JFrame; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.JScrollPane; +import javax.swing.ListCellRenderer; +import java.awt.Component; +import java.awt.FlowLayout; +import java.awt.GridLayout; +import javax.swing.BoxLayout; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; +import java.awt.Container; +import javax.swing.ImageIcon; +import java.awt.Image; +import java.awt.Toolkit; +import java.net.URL; +import java.awt.Rectangle; + +public class JListView extends JList { + + + static Category cat = Category.getInstance(JListView.class.getName()); + + + //JListViewModel model; + PatternLayout layout; + + static LoggingEvent proto = new LoggingEvent("x", cat, Priority.ERROR, + "Message ", new Throwable()); + + public + JListView(JListViewModel model) { + super(model); + layout = new PatternLayout("%r %p %c [%t] - %m"); + //this.setModel(model); + this.setCellRenderer(new MyCellRenderer()); + // setFixedCellWidth(10); + //setFixedCellHeight(20); + + } + + public + void add(LoggingEvent event) { + ((JListViewModel)getModel()).add(event); + } + + /* + public + Dimension getPreferredSize() { + System.out.println("getPreferredSize() called"); + return super.getPreferredSize(); + } + + + public + int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, + int direction) { + System.out.println("getScrollableUnitIncrement called with " + visibleRect + + "orientation: "+orientation+", direction: "+direction); + return super.getScrollableUnitIncrement(visibleRect, orientation, + direction); + } + + public + int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, + int direction) { + System.out.println("getScrollableBlockIncrement called with " + + visibleRect + "orientation: "+orientation+ + ", direction: "+direction); + return super.getScrollableBlockIncrement(visibleRect, orientation, + direction); + } + */ + + //public + //boolean getScrollableTracksViewportWidth() { + //System.out.println("getScrollableTracksViewportWidth called."); + //return true; + //boolean b = super.getScrollableTracksViewportWidth(); + //System.out.println("result is: "+b); + //return b; + //} + + //public + //boolean getScrollableTracksViewportHeight() { + // System.out.println("getScrollableTracksViewportHeight called."); + // return true; + //boolean b = super.getScrollableTracksViewportHeight(); + //System.out.println("result is: "+b); + //return b; + //} + + //public + //int getFirstVisibleIndex() { + //int r = getFirstVisibleIndex(); + // System.out.println("----------getFirstVisibleIndex called, result: "+r); + //return r; + //} + + //public + //Object getPrototypeCellValue() { + //return proto; + //} + + + + static public void main(String[] args) { + + JFrame frame = new JFrame("JListView test"); + Container container = frame.getContentPane(); + + JListView view = new JListView(new JListViewModel(Integer.parseInt(args[0]))); + + + JScrollPane sp = new JScrollPane(view); + sp.setPreferredSize(new Dimension(250, 80)); + + container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS)); + //container.add(view); + container.add(sp); + + JButton b1 = new JButton("Add 1"); + JButton b10 = new JButton("Add 10"); + JButton b100 = new JButton("Add 100"); + JButton b1000 = new JButton("Add 1000"); + JButton b10000 = new JButton("Add 10000"); + + JPanel panel = new JPanel(new GridLayout(0,1)); + container.add(panel); + + panel.add(b1); + panel.add(b10); + panel.add(b100); + panel.add(b1000); + panel.add(b10000); + + + AddAction a1 = new AddAction(view, 1); + AddAction a10 = new AddAction(view, 10); + AddAction a100 = new AddAction(view, 100); + AddAction a1000 = new AddAction(view, 1000); + AddAction a10000 = new AddAction(view, 10000); + + b1.addActionListener(a1); + b10.addActionListener(a10); + b100.addActionListener(a100); + b1000.addActionListener(a1000); + b10000.addActionListener(a10000); + + frame.setVisible(true); + frame.setSize(new Dimension(700,700)); + + long before = System.currentTimeMillis(); + + int RUN = 1000; + int i = 0; + while(i++ < RUN) { + LoggingEvent event0 = new LoggingEvent("x", cat, Priority.ERROR, + "Message "+i, null); + + Throwable t = new Exception("hello "+i); + LoggingEvent event1 = new LoggingEvent("x", cat, Priority.ERROR, + "Message "+i, t); + + + if(i % 10 == 0) { + event1.getThreadName(); + view.add(event1); + } else { + event0.getThreadName(); + view.add(event0); + } + } + + long after = System.currentTimeMillis(); + System.out.println("Time taken :"+ ((after-before)*1000/RUN)); + + } + + class MyCellRenderer extends JTextArea implements ListCellRenderer { + + Object o = new Object(); + int i = 0; + final ImageIcon longIcon = new ImageIcon("RedFlag.gif"); + + public + MyCellRenderer() { + System.out.println("----------------------"); + + } + + + + public + int getTabSize() { + return 2; + } + + public Image loadIcon ( String path ) { + Image img = null; + try { + URL url = ClassLoader.getSystemResource(path); + img = (Image) (Toolkit.getDefaultToolkit()).getImage(url); + } catch (Exception e) { + System.out.println("Exception occured: " + e.getMessage() + + " - " + e ); + } + return (img); + } + + public Component getListCellRendererComponent(JList list, + Object value, + int index, // cell index + boolean isSelected, + boolean cellHasFocus) { + + // System.out.println(o + " ============== " + i++); + //LogLog.error("=======", new Exception()); + //setIcon(longIcon); + if(value instanceof LoggingEvent) { + LoggingEvent event = (LoggingEvent) value; + String str = layout.format(event); + String t = event.getThrowableInformation(); + + if(t != null) { + setText(str + Layout.LINE_SEP + t); + } else { + setText(str); + } + + } else { + setText(value.toString()); + } + + + return this; + } + } +} + + + +class JListViewModel extends AbstractListModel { + + CyclicBuffer cb; + + JListViewModel(int size) { + cb = new CyclicBuffer(size); + } + + public + void add(LoggingEvent event) { + //System.out.println("JListViewModel.add called"); + cb.add(event); + int j = cb.length(); + fireContentsChanged(this, 0, j); + } + + + + public + Object getElementAt(int index) { + return cb.get(index); + } + + public + int getSize() { + return cb.length(); + } + +} + +class AddAction implements ActionListener { + + Thread t; + + static int counter = 0; + + public + AddAction(JListView view, int burst) { + this.t = new AddThread(view, burst); + t.start(); + } + + public + void actionPerformed(ActionEvent e) { + System.out.println("Action occured"); + synchronized(t) { + t.notify(); + } + } + + class AddThread extends Thread { + int burst; + JListView view; + + Category cat = Category.getInstance("x"); + + AddThread(JListView view, int burst) { + super(); + this.burst = burst; + this.view = view; + setName("AddThread"+burst); + } + + public + void run() { + + while(true) { + synchronized(this) { + try { + this.wait(); + } catch(Exception e) { + } + } + for(int i = 0; i < burst; i++) { + LoggingEvent event = new LoggingEvent("x", cat, Priority.DEBUG, + "Message "+counter, null); + + event.getThreadName(); + if(counter % 50 == 0) { + //event.throwable = new Exception("hello "+counter); + } + counter++; + view.add(event); + } + } + } + } +} diff --git a/contribs/SvenReimers/gui/JTableAppender.java b/contribs/SvenReimers/gui/JTableAppender.java new file mode 100644 index 0000000000..32cc23ac83 --- /dev/null +++ b/contribs/SvenReimers/gui/JTableAppender.java @@ -0,0 +1,237 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.log4j.gui; + +import org.apache.log4j.helpers.CyclicBuffer; +import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.Priority; +import org.apache.log4j.Category; +import org.apache.log4j.Layout; +import org.apache.log4j.PatternLayout; +import org.apache.log4j.spi.LoggingEvent; + +import javax.swing.JList; +import javax.swing.AbstractListModel; +import javax.swing.JFrame; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.JTextArea; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableCellRenderer; +import javax.swing.JScrollPane; +import javax.swing.ListCellRenderer; +import java.awt.Component; +import java.awt.FlowLayout; +import javax.swing.BoxLayout; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; +import java.awt.Container; +import javax.swing.ImageIcon; +import java.awt.Image; +import java.awt.Toolkit; +import java.net.URL; +import java.awt.Rectangle; + +public class JTableAppender extends JTable { + + + static Category cat = Category.getInstance(JTableAppender.class.getName()); + + PatternLayout layout; + + public + JTableAppender() { + layout = new PatternLayout("%r %p %c [%t] - %m"); + this.setDefaultRenderer(Object.class, new Renderer()); + + } + + public + void add(LoggingEvent event) { + ((JTableAppenderModel)getModel()).add(event); + } + + public + Dimension getPreferredSize() { + System.out.println("getPreferredSize() called"); + return super.getPreferredSize(); + } + + static public void main(String[] args) { + + JFrame frame = new JFrame("JListView test"); + Container container = frame.getContentPane(); + + JTableAppender appender = new JTableAppender(); + + JTableAppenderModel model = new + JTableAppenderModel(Integer.parseInt(args[0])); + appender.setModel(model); + //appender.createDefaultColumnsFromModel(); + + + JScrollPane sp = new JScrollPane(appender); + sp.setPreferredSize(new Dimension(250, 80)); + + container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS)); + //container.add(view); + container.add(sp); + + JButton button = new JButton("ADD"); + container.add(button); + + + button.addActionListener(new JTableAddAction(appender)); + + frame.setVisible(true); + frame.setSize(new Dimension(700,700)); + + long before = System.currentTimeMillis(); + + int RUN = 10000; + int i = 0; + while(i++ < RUN) { + LoggingEvent event = new LoggingEvent("x", cat, Priority.ERROR, + "Message "+i, null); + event.getThreadName(); + if(i % 10 == 0) { + //event.throwable = new Exception("hello "+i); + } + appender.add(event); + } + + long after = System.currentTimeMillis(); + System.out.println("Time taken :"+ ((after-before)*1000/RUN)); + + } + + class Renderer extends JTextArea implements TableCellRenderer { + + Object o = new Object(); + int i = 0; + + public + Renderer() { + System.out.println("Render() called ----------------------"); + } + + public Component getTableCellRendererComponent(JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column) { + + System.out.println(o + " ============== " + i++); + //LogLog.error("=======", new Exception()); + //setIcon(longIcon); + if(value instanceof LoggingEvent) { + LoggingEvent event = (LoggingEvent) value; + String str = layout.format(event); + String t = event.getThrowableInformation(); + + if(t != null) { + System.out.println("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); + setText(str + Layout.LINE_SEP + t); + } else { + setText(str); + } + + } else { + setText(value.toString()); + } + + + return this; + } + } +} + + + +class JTableAppenderModel extends AbstractTableModel { + + CyclicBuffer cb; + + JTableAppenderModel(int size) { + cb = new CyclicBuffer(size); + } + + public + void add(LoggingEvent event) { + //System.out.println("JListViewModel.add called"); + cb.add(event); + int j = cb.length(); + + fireTableDataChanged(); + + } + public + int getColumnCount() { + return 1; + } + + public int getRowCount() { + return cb.length(); + } + + //public + //Class getColumnClass(int index) { + // System.out.println("getColumnClass called " + index); + // return LoggingEvent.class; + //} + + public + Object getValueAt(int row, int col) { + return cb.get(row); + } +} + + +class JTableAddAction implements ActionListener { + + int j; + JTableAppender appender; + + Category cat = Category.getInstance("x"); + + public + JTableAddAction(JTableAppender appender) { + this.appender = appender; + j = 0; + } + + public + void actionPerformed(ActionEvent e) { + System.out.println("Action occured"); + + LoggingEvent event = new LoggingEvent("x", cat, Priority.DEBUG, + "Message "+j, null); + + if(j % 5 == 0) { + //event.throwable = new Exception("hello "+j); + } + j++; + appender.add(event); + } +} diff --git a/contribs/SvenReimers/gui/TextPaneAppender.java b/contribs/SvenReimers/gui/TextPaneAppender.java new file mode 100644 index 0000000000..6b8fce523d --- /dev/null +++ b/contribs/SvenReimers/gui/TextPaneAppender.java @@ -0,0 +1,355 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.gui; + + +import java.awt.Color; +import java.awt.Image; +import java.awt.Toolkit; +import java.io.*; +import java.net.URL; +import java.util.Enumeration; +import java.util.StringTokenizer; +import java.util.Hashtable; + +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JTextPane; +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyledDocument; +import javax.swing.text.TabSet; +import javax.swing.text.TabStop; + +import org.apache.log4j.*; + +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.helpers.Loader; +import org.apache.log4j.helpers.QuietWriter; +import org.apache.log4j.helpers.TracerPrintWriter; +import org.apache.log4j.helpers.OptionConverter; + + +/** + * Experimental TextPaneAppender.
+ * + * + * Created: Sat Feb 26 18:50:27 2000
+ * + * @author Sven Reimers + */ + +public class TextPaneAppender extends AppenderSkeleton { + + JTextPane textpane; + StyledDocument doc; + TracerPrintWriter tp; + StringWriter sw; + QuietWriter qw; + Hashtable attributes; + Hashtable icons; + + private String label; + + private boolean fancy; + + final String LABEL_OPTION = "Label"; + final String COLOR_OPTION_FATAL = "Color.Emerg"; + final String COLOR_OPTION_ERROR = "Color.Error"; + final String COLOR_OPTION_WARN = "Color.Warn"; + final String COLOR_OPTION_INFO = "Color.Info"; + final String COLOR_OPTION_DEBUG = "Color.Debug"; + final String COLOR_OPTION_BACKGROUND = "Color.Background"; + final String FANCY_OPTION = "Fancy"; + final String FONT_NAME_OPTION = "Font.Name"; + final String FONT_SIZE_OPTION = "Font.Size"; + + public static Image loadIcon ( String path ) { + Image img = null; + try { + URL url = ClassLoader.getSystemResource(path); + img = (Image) (Toolkit.getDefaultToolkit()).getImage(url); + } catch (Exception e) { + System.out.println("Exception occured: " + e.getMessage() + + " - " + e ); + } + return (img); + } + + public TextPaneAppender(Layout layout, String name) { + this(); + this.layout = layout; + this.name = name; + setTextPane(new JTextPane()); + createAttributes(); + createIcons(); + } + + public TextPaneAppender() { + super(); + setTextPane(new JTextPane()); + createAttributes(); + createIcons(); + this.label=""; + this.sw = new StringWriter(); + this.qw = new QuietWriter(sw, errorHandler); + this.tp = new TracerPrintWriter(qw); + this.fancy =true; + } + + public + void close() { + + } + + private void createAttributes() { + Priority prio[] = Priority.getAllPossiblePriorities(); + + attributes = new Hashtable(); + for (int i=0; i= 255 ? res : res + ","+c.getAlpha(); + } + + public + void setLayout(Layout layout) { + this.layout=layout; + } + + public + void setName(String name) { + this.name = name; + } + + + public + void setTextPane(JTextPane textpane) { + this.textpane=textpane; + textpane.setEditable(false); + textpane.setBackground(Color.lightGray); + this.doc=textpane.getStyledDocument(); + } + + private + void setColor(Priority p, String v) { + StyleConstants.setForeground( + (MutableAttributeSet)attributes.get(p),parseColor(v)); + } + + private + String getColor(Priority p) { + Color c = StyleConstants.getForeground( + (MutableAttributeSet)attributes.get(p)); + return c == null ? null : colorToString(c); + } + + ///////////////////////////////////////////////////////////////////// + // option setters and getters + + public + void setLabel(String label) { + this.label = label; + } + public + String getLabel() { + return label; + } + + public + void setColorEmerg(String color) { + setColor(Priority.FATAL, color); + } + public + String getColorEmerg() { + return getColor(Priority.FATAL); + } + + public + void setColorError(String color) { + setColor(Priority.ERROR, color); + } + public + String getColorError() { + return getColor(Priority.ERROR); + } + + public + void setColorWarn(String color) { + setColor(Priority.WARN, color); + } + public + String getColorWarn() { + return getColor(Priority.WARN); + } + + public + void setColorInfo(String color) { + setColor(Priority.INFO, color); + } + public + String getColorInfo() { + return getColor(Priority.INFO); + } + + public + void setColorDebug(String color) { + setColor(Priority.DEBUG, color); + } + public + String getColorDebug() { + return getColor(Priority.DEBUG); + } + + public + void setColorBackground(String color) { + textpane.setBackground(parseColor(color)); + } + public + String getColorBackground() { + return colorToString(textpane.getBackground()); + } + + public + void setFancy(boolean fancy) { + this.fancy = fancy; + } + public + boolean getFancy() { + return fancy; + } + + public + void setFontSize(int size) { + Enumeration e = attributes.elements(); + while (e.hasMoreElements()) { + StyleConstants.setFontSize((MutableAttributeSet)e.nextElement(),size); + } + return; + } + + public + int getFontSize() { + AttributeSet attrSet = (AttributeSet) attributes.get(Priority.INFO); + return StyleConstants.getFontSize(attrSet); + } + + public + void setFontName(String name) { + Enumeration e = attributes.elements(); + while (e.hasMoreElements()) { + StyleConstants.setFontFamily((MutableAttributeSet)e.nextElement(),name); + } + return; + } + + public + String getFontName() { + AttributeSet attrSet = (AttributeSet) attributes.get(Priority.INFO); + return StyleConstants.getFontFamily(attrSet); + } + + public + boolean requiresLayout() { + return true; + } +} // TextPaneAppender + + + diff --git a/contribs/SvenReimers/gui/examples/TextPaneAppenderExample.java b/contribs/SvenReimers/gui/examples/TextPaneAppenderExample.java new file mode 100644 index 0000000000..bd5f9d3a16 --- /dev/null +++ b/contribs/SvenReimers/gui/examples/TextPaneAppenderExample.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.gui.examples; + +import java.awt.BorderLayout; +import java.awt.event.*; +import javax.swing.*; +import org.apache.log4j.*; +import org.apache.log4j.gui.*; + + + +public class TextPaneAppenderExample implements ActionListener { + + JFrame mainframe; + ButtonGroup priorities; + TextPaneAppender tpa; + Category gui; + Priority prio[]; + JTabbedPane logview; + + + public TextPaneAppenderExample () { + mainframe = new JFrame("Testing the TextPaneAppender..."); + mainframe.setSize(300,300); + logview = new JTabbedPane(); + createLogger(); + createMenuBar(); + mainframe.setVisible(true); + mainframe.getContentPane().add(logview); + } + + public void createLogger() { + tpa = new TextPaneAppender(new PatternLayout("%-5p %d [%t]: %m%n"),"Debug"); + logview.addTab("Events ...",new JScrollPane(tpa.getTextPane())); + gui = Category.getInstance(this.getClass().getName()); + gui.addAppender(tpa); + } + + public void createMenuBar() { + JMenu file = new JMenu("File"); + JMenuItem exit = new JMenuItem("Exit"); + exit.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + System.exit(0); + } + }); + file.add(exit); + JMenuBar mb = new JMenuBar(); + mb.add(file); + + JMenu logevent = new JMenu("LoggingEvents"); + JMenu selectprio = new JMenu("Priority"); + + prio = Priority.getAllPossiblePriorities(); + JRadioButtonMenuItem priority[]= new JRadioButtonMenuItem[prio.length]; + priorities = new ButtonGroup(); + + for (int i=0; iThe JDBCAppender is configurable at runtime by setting options in two alternatives :

+ +

1. Use a configuration-file

+

Define the options in a file (example) and call a PropertyConfigurator.configure(filename) in your code.

+

2. Use the methods of JDBCAppender to do it

+

Call JDBCAppender::setOption(JDBCAppender.xxx_OPTION, String value) to do it analogically without a configuration-file (example)

+
+ +

All available options are defined as static String-constants in JDBCAppender named xxx_OPTION.

+ +

Here is a description of all available options :

+ +

1. Database-options to connect to the database

+

- URL_OPTION : a database url of the form jdbc:subprotocol:subname

+

- USERNAME_OPTION : the database user on whose behalf the connection is being made

+

- PASSWORD_OPTION : the user's password

+ +

2. Connector-option to specify your own JDBCConnectionHandler

+

- CONNECTOR_OPTION : a classname which is implementing the JDBCConnectionHandler-interface

+

This interface is used to get a customized connection.

+

If in addition the database-options are given, these options will be used as arguments for the JDBCConnectionHandler-interface to get a connection.

+

Else if no database-options are given, the JDBCConnectionHandler-interface is called without them.

+

Else if this option is not defined, the database-options are required to open a connection by the JDBCAppender.

+ +

3. SQL-option to specify a static sql-statement which will be performed with every occuring message-event

+

- SQL_OPTION : a sql-statement which will be used to write to the database

+

Use the variable @MSG@ on a location in the statement, which has to be dynamically replaced by the message-text.

+

If you give this option, the table-option and columns-option will be ignored !

+ +

4. Table-option to specify a table contained by the database

+

- TABLE_OPTION : the table in which the logging will be done

+ +

5. Columns-option to describe the important columns of the table (Not nullable columns are mandatory to describe!)

+

- COLUMNS_OPTION : a formatted list of column-descriptions

+

Each column description consists of

+ +

- the name of the column (required)

+

- a logtype which is a static constant of class LogType (required)

+

- and a value which depends by the LogType (optional/required, depending by logtype)

+
+

Here is a description of the available logtypes of class {@link LogType} and how to handle the value:

+ +

o MSG = a value will be ignored, the column will get the message. (One columns need to be of this type!)

+

o STATIC = the value will be filled into the column with every logged message. (Ensure that the type of value can be casted into the sql-type of the column!)

+

o ID = value must be a classname, which implements the JDBCIDHandler-interface.

+

o TIMESTAMP = a value will be ignored, the column will be filled with a actually timestamp with every logged message.

+

o EMPTY = a value will be ignored, the column will be ignored when writing to the database (Ensure to fill not nullable columns by a database trigger!)

+
+

If there are more than one column to describe, the columns must be separated by a Tabulator-delimiter (unicode0008) !

+

The arguments of a column-description must be separated by the delimiter '~' !

+

(Example : name1~logtype1~value1 name2~logtype2~value2...)

+ +

6. Layout-options to define the layout of the messages (optional)

+

- _ : the layout wont be set by a xxx_OPTION

+

See the configuration-file and code examples below...

+

The default is a layout of the class {@link org.apache.log4j.PatternLayout} with the pattern=%m which representate only the message.

+ +

7. Buffer-option to define the size of the message-event-buffer (optional)

+

- BUFFER_OPTION : define how many messages will be buffered until they will be updated to the database.

+

The default is buffer=1, which will do a update with every happened message-event.

+ +

8. Commit-option to define a auto-commitment

+

- COMMIT_OPTION : define whether updated messages should be committed to the database (Y) or not (N).

+

The default is commit=Y.

+
+ +

The sequence of some options is important :

+ +

1. Connector-option OR/AND Database-options

+

Any database connection is required !

+

2. (Table-option AND Columns-option) OR SQL-option

+

Anything of that is required ! Whether where to write something OR what to write somewhere...;-)

+

3. All other options can be set at any time...

+

The other options are optional and have a default initialization, which can be customized.

+
+ +

Here is a configuration-file example, which can be used as argument for the PropertyConfigurator : configfile_example.txt

+ +

Here is a code-example to configure the JDBCAppender with a configuration-file : code_example1.java

+ +

Here is a another code-example to configure the JDBCAppender without a configuration-file : code_example2.java

+ + + +

Author : Thomas Fenner

+ +@since 1.0 +*/ +public class JDBCAppender extends AppenderSkeleton +{ + /** + A database-option to to set a database url of the form jdbc:subprotocol:subname. + */ + public static final String URL_OPTION = "url"; + + /** + A database-option to set the database user on whose behalf the connection is being made. + */ + public static final String USERNAME_OPTION = "username"; + + /** + A database-option to set the user's password. + */ + public static final String PASSWORD_OPTION = "password"; + + /** + A table-option to specify a table contained by the database + */ + public static final String TABLE_OPTION = "table"; + + /** + A connector-option to specify your own JDBCConnectionHandler + */ + public static final String CONNECTOR_OPTION = "connector"; + + /** + A columns-option to describe the important columns of the table + */ + public static final String COLUMNS_OPTION = "columns"; + + /** + A sql-option to specify a static sql-statement which will be performed with every occuring message-event + */ + public static final String SQL_OPTION = "sql"; + + /** + A buffer-option to define the size of the message-event-buffer + */ + public static final String BUFFER_OPTION = "buffer"; + + /** + A commit-option to define a auto-commitment + */ + public static final String COMMIT_OPTION = "commit"; + + + //Variables to store the options values setted by setOption() : + private String url = null; + private String username = null; + private String password = null; + private String table = null; + private String connection_class = null; + private String sql = null; + private boolean docommit = true; + private int buffer_size = 1; + private JDBCConnectionHandler connectionHandler = null; + + //This buffer stores message-events. + //When the buffer_size is reached, the buffer will be flushed and the messages will updated to the database. + private ArrayList buffer = new ArrayList(); + + //Database-connection + private Connection con = null; + + //This class encapsulate the logic which is necessary to log into a table + private JDBCLogger jlogger = new JDBCLogger(); + + //Flags : + //A flag to indicate a established database connection + private boolean connected = false; + //A flag to indicate configuration status + private boolean configured = false; + //A flag to indicate that everything is ready to get append()-commands. + private boolean ready = false; + + /** + If program terminates close the database-connection and flush the buffer + */ + public void finalize() + { + close(); + super.finalize(); + } + + /** + Internal method. Returns a array of strings containing the available options which can be set with method setOption() + */ + public String[] getOptionStrings() + { + // The sequence of options in this string is important, because setOption() is called this way ... + return new String[]{CONNECTOR_OPTION, URL_OPTION, USERNAME_OPTION, PASSWORD_OPTION, SQL_OPTION, TABLE_OPTION, COLUMNS_OPTION, BUFFER_OPTION, COMMIT_OPTION}; + } + + + /** + Sets all necessary options + */ + public void setOption(String _option, String _value) + { + _option = _option.trim(); + _value = _value.trim(); + + if(_option == null || _value == null) return; + if(_option.length() == 0 || _value.length() == 0) return; + + _value = _value.trim(); + + if(_option.equals(CONNECTOR_OPTION)) + { + if(!connected) connection_class = _value; + } + else if(_option.equals(URL_OPTION)) + { + if(!connected) url = _value; + } + else if(_option.equals(USERNAME_OPTION)) + { + if(!connected) username = _value; + } + else if(_option.equals(PASSWORD_OPTION)) + { + if(!connected) password = _value; + } + else if(_option.equals(SQL_OPTION)) + { + sql = _value; + } + else if(_option.equals(TABLE_OPTION)) + { + if(sql != null) return; + table = _value; + } + else if(_option.equals(COLUMNS_OPTION)) + { + if(sql != null) return; + + String name = null; + int logtype = -1; + String value = null; + String column = null; + String arg = null; + int num_args = 0; + int num_columns = 0; + StringTokenizer st_col; + StringTokenizer st_arg; + + //Columns are TAB-separated + st_col = new StringTokenizer(_value, " "); + + num_columns = st_col.countTokens(); + + if(num_columns < 1) + { + errorHandler.error("JDBCAppender::setOption(), Invalid COLUMN_OPTION value : " + _value + " !"); + return; + } + + for(int i=1; i<=num_columns; i++) + { + column = st_col.nextToken(); + + //Arguments are ~-separated + st_arg = new StringTokenizer(column, "~"); + + num_args = st_arg.countTokens(); + + if(num_args < 2) + { + errorHandler.error("JDBCAppender::setOption(), Invalid COLUMN_OPTION value : " + _value + " !"); + return; + } + + for(int j=1; j<=num_args; j++) + { + arg = st_arg.nextToken(); + + if(j == 1) name = arg; + else if(j == 2) + { + try + { + logtype = Integer.parseInt(arg); + } + catch(Exception e) + { + logtype = LogType.parseLogType(arg); + } + + if(!LogType.isLogType(logtype)) + { + errorHandler.error("JDBCAppender::setOption(), Invalid COLUMN_OPTION LogType : " + arg + " !"); + return; + } + } + else if(j == 3) value = arg; + } + + if(!setLogType(name, logtype, value)) return; + } + } + else if(_option.equals(BUFFER_OPTION)) + { + try + { + buffer_size = Integer.parseInt(_value); + } + catch(Exception e) + { + errorHandler.error("JDBCAppender::setOption(), Invalid BUFFER_OPTION value : " + _value + " !"); + return; + } + } + else if(_option.equals(COMMIT_OPTION)) + { + docommit = _value.equals("Y"); + } + + if(_option.equals(SQL_OPTION) || _option.equals(TABLE_OPTION)) + { + if(!configured) configure(); + } + } + + /** + Internal method. Returns true, you may define your own layout... + */ + public boolean requiresLayout() + { + return true; + } + + + /** + Internal method. Close the database connection & flush the buffer. + */ + public void close() + { + flush_buffer(); + if(connection_class == null) + { + try{con.close();}catch(Exception e){errorHandler.error("JDBCAppender::close(), " + e);} + } + this.closed = true; + } + + + /** + You have to call this function for all provided columns of your log-table ! + */ + public boolean setLogType(String _name, int _logtype, Object _value) + { + if(sql != null) return true; + + if(!configured) + { + if(!configure()) return false; + } + + try + { + jlogger.setLogType(_name, _logtype, _value); + } + catch(Exception e) + { + errorHandler.error("JDBCAppender::setLogType(), " + e); + return false; + } + + return true; + } + + + /** + Internal method. Appends the message to the database table. + */ + public void append(LoggingEvent event) + { + if(!ready) + { + if(!ready()) + { + errorHandler.error("JDBCAppender::append(), Not ready to append !"); + return; + } + } + + buffer.add(event); + + if(buffer.size() >= buffer_size) flush_buffer(); + } + + + /** + Internal method. Flushes the buffer. + */ + public void flush_buffer() + { + try + { + int size = buffer.size(); + + if(size < 1) return; + + for(int i=0; iAuthor : Thomas Fenner

+ +@since 1.0 +*/ +public interface JDBCConnectionHandler +{ + /**Get a connection*/ + Connection getConnection(); + /**Get a defined connection*/ + Connection getConnection(String _url, String _username, String _password); +} + + diff --git a/contribs/ThomasFenner/JDBCIDHandler.java b/contribs/ThomasFenner/JDBCIDHandler.java new file mode 100644 index 0000000000..9e6a765da7 --- /dev/null +++ b/contribs/ThomasFenner/JDBCIDHandler.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.klopotek.utils.log; + + +/** +This interface has to be implemented to provide ID-columns with unique IDs and its used in class JDBCLogger. + +

Author : Thomas Fenner

+ +@since 1.0 +*/ +public interface JDBCIDHandler +{ + /**Get a unique ID*/ + Object getID(); +} + + + diff --git a/contribs/ThomasFenner/JDBCLogger.java b/contribs/ThomasFenner/JDBCLogger.java new file mode 100644 index 0000000000..5edf2e8c43 --- /dev/null +++ b/contribs/ThomasFenner/JDBCLogger.java @@ -0,0 +1,468 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.klopotek.utils.log; + +import java.sql.*; +import java.util.*; +import org.apache.log4j.*; +import org.apache.log4j.helpers.*; +import org.apache.log4j.spi.*; + + +/** +This class encapsulate the logic which is necessary to log into a table. +Used by JDBCAppender + +

Author : Thomas Fenner

+ +@since 1.0 +*/ +public class JDBCLogger +{ + //All columns of the log-table + private ArrayList logcols = null; + //Only columns which will be provided by logging + private String column_list = null; + //Number of all columns + private int num = 0; + //Status for successful execution of method configure() + private boolean isconfigured = false; + //Status for ready to do logging with method append() + private boolean ready = false; + //This message will be filled with a error-string when method ready() failes, and can be got by calling getMsg() + private String errormsg = ""; + + private Connection con = null; + private Statement stmt = null; + private ResultSet rs = null; + private String table = null; + + //Variables for static SQL-statement logging + private String sql = null; + private String new_sql = null; + private String new_sql_part1 = null; + private String new_sql_part2 = null; + private static final String msg_wildcard = "@MSG@"; + private int msg_wildcard_pos = 0; + + /** + Writes a message into the database table. + Throws an exception, if an database-error occurs ! + */ + public void append(String _msg) throws Exception + { + if(!ready) if(!ready()) throw new Exception("JDBCLogger::append(), Not ready to append !"); + + if(sql != null) + { + appendSQL(_msg); + return; + } + + LogColumn logcol; + + rs.moveToInsertRow(); + + for(int i=0; i 0) + { + new_sql = new_sql_part1 + _msg + new_sql_part2; + } + else new_sql = sql; + + try + { + stmt.executeUpdate(new_sql); + } + catch(Exception e) + { + errormsg = new_sql; + throw e; + } + } + + + /** + Configures this class, by reading in the structure of the log-table + Throws an exception, if an database-error occurs ! + */ + public void configureTable(String _table) throws Exception + { + if(isconfigured) return; + + //Fill logcols with META-informations of the table-columns + stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); + rs = stmt.executeQuery("SELECT * FROM " + _table + " WHERE 1 = 2"); + + LogColumn logcol; + + ResultSetMetaData rsmd = rs.getMetaData(); + + num = rsmd.getColumnCount(); + + logcols = new ArrayList(num); + + for(int i=1; i<=num; i++) + { + logcol = new LogColumn(); + logcol.name = rsmd.getColumnName(i).toUpperCase(); + logcol.type = rsmd.getColumnTypeName(i); + logcol.nullable = (rsmd.isNullable(i) == rsmd.columnNullable); + logcol.isWritable = rsmd.isWritable(i); + if(!logcol.isWritable) logcol.ignore = true; + logcols.add(logcol); + } + + table = _table; + + isconfigured = true; + } + + /** + Configures this class, by storing and parsing the given sql-statement. + Throws an exception, if somethings wrong ! + */ + public void configureSQL(String _sql) throws Exception + { + if(isconfigured) return; + + if(!isConnected()) throw new Exception("JDBCLogger::configureSQL(), Not connected to database !"); + + if(_sql == null || _sql.trim().equals("")) throw new Exception("JDBCLogger::configureSQL(), Invalid SQL-Statement !"); + + sql = _sql.trim(); + + stmt = con.createStatement(); + + msg_wildcard_pos = sql.indexOf(msg_wildcard); + + if(msg_wildcard_pos > 0) + { + new_sql_part1 = sql.substring(0, msg_wildcard_pos-1) + "'"; + //between the message... + new_sql_part2 = "'" + sql.substring(msg_wildcard_pos+msg_wildcard.length()); + } + + isconfigured = true; + } + + /** + Sets a connection. Throws an exception, if the connection is not open ! + */ + public void setConnection(Connection _con) throws Exception + { + con = _con; + + if(!isConnected()) throw new Exception("JDBCLogger::setConnection(), Given connection isnt connected to database !"); + } + + + /** + Sets a columns logtype (LogTypes) and value, which depends on that logtype. + Throws an exception, if the given arguments arent correct ! + */ + public void setLogType(String _name, int _logtype, Object _value) throws Exception + { + if(!isconfigured) throw new Exception("JDBCLogger::setLogType(), Not configured !"); + + //setLogType() makes only sense for further configuration of configureTable() + if(sql != null) return; + + _name = _name.toUpperCase(); + + if(_name == null || !(_name.trim().length() > 0)) throw new Exception("JDBCLogger::setLogType(), Missing argument name !"); + if(!LogType.isLogType(_logtype)) throw new Exception("JDBCLogger::setLogType(), Invalid logtype '" + _logtype + "' !"); + if((_logtype != LogType.MSG && _logtype != LogType.EMPTY) && _value == null) throw new Exception("JDBCLogger::setLogType(), Missing argument value !"); + + LogColumn logcol; + + for(int i=0; i= setted priority will be logged to the database. + cat.debug("debug"); //this not, because Priority DEBUG is less than INFO + cat.info("info"); + cat.error("error"); + cat.fatal("fatal"); + } +} + +// Here is a code example to configure the JDBCAppender without a configuration-file : +/* +import org.apache.log4j.*; +import java.sql.*; +import java.lang.*; +import java.util.*; + +public class Log4JTest +{ + // Create a category instance for this class + static Category cat = Category.getInstance(Log4JTest.class.getName()); + + public static void main(String[] args) + { + // A JDBCIDHandler + MyIDHandler idhandler = new MyIDHandler(); + + // Ensure to have all necessary drivers installed ! + try + { + Driver d = (Driver)(Class.forName("oracle.jdbc.driver.OracleDriver").newInstance()); + DriverManager.registerDriver(d); + } + catch(Exception e){} + + // Set the priority which messages have to be logged + cat.setPriority(Priority.DEBUG); + + // Create a new instance of JDBCAppender + JDBCAppender ja = new JDBCAppender(); + + // Set options with method setOption() + ja.setOption(JDBCAppender.CONNECTOR_OPTION, "MyConnectionHandler"); + ja.setOption(JDBCAppender.URL_OPTION, "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(COMMUNITY=tcp.world)(PROTOCOL=TCP)(Host=LENZI)(Port=1521))(ADDRESS=(COMMUNITY=tcp.world)(PROTOCOL=TCP)(Host=LENZI)(Port=1526)))(CONNECT_DATA=(SID=LENZI)))"); + ja.setOption(JDBCAppender.USERNAME_OPTION, "mex_pr_dev60"); + ja.setOption(JDBCAppender.PASSWORD_OPTION, "mex_pr_dev60"); + + ja.setOption(JDBCAppender.TABLE_OPTION, "logtest"); + + // There are two ways to setup the column-descriptions : + // 1. Use the the method setOption(JDBCAppender.COLUMNS_OPTION, column-description) + //ja.setOption(JDBCAppender.COLUMNS_OPTION, "id_seq~EMPTY id~ID~MyIDHandler msg~MSG created_on~TIMESTAMP created_by~STATIC~:-) Thomas Fenner (t.fenner@klopotek.de)"); + // 2. Use the better way of coding with method setLogType(String columnname, int LogType.xxx, Object xxx) + ja.setLogType("id_seq", LogType.EMPTY, ""); + ja.setLogType("id", LogType.ID, idhandler); + ja.setLogType("msg", LogType.MSG, ""); + ja.setLogType("created_on", LogType.TIMESTAMP, ""); + ja.setLogType("created_by", LogType.STATIC, "FEN"); + + // If you just want to perform a static sql-statement, forget about the table- and columns-options, + // and use this one : + //ja.setOption(JDBCAppender.SQL_OPTION, "INSERT INTO LOGTEST (id, msg, created_on, created_by) VALUES (1, @MSG@, sysdate, 'me')"); + + // other options + //ja.setOption(JDBCAppender.BUFFER_OPTION, "1"); + //ja.setOption(JDBCAppender.COMMIT_OPTION, "Y"); + + // Define a layout + //ja.setLayout(new PatternLayout("%m")); + + // Add the appender to a category + cat.addAppender(ja); + + // These messages with Priority >= setted priority will be logged to the database. + cat.debug("debug"); + cat.info("info"); + cat.error("error"); + cat.fatal("fatal"); + } +} +*/ + +// Implement a sample JDBCConnectionHandler +class MyConnectionHandler implements JDBCConnectionHandler +{ + Connection con = null; + //Default connection + String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(COMMUNITY=tcp.world)(PROTOCOL=TCP)(Host=LENZI)(Port=1521))(ADDRESS=(COMMUNITY=tcp.world)(PROTOCOL=TCP)(Host=LENZI)(Port=1526)))(CONNECT_DATA=(SID=LENZI)))"; + String username = "mex_pr_dev60"; + String password = "mex_pr_dev60"; + + public Connection getConnection() + { + return getConnection(url, username, password); + } + + public Connection getConnection(String _url, String _username, String _password) + { + try + { + if(con != null && !con.isClosed()) con.close(); + con = DriverManager.getConnection(_url, _username, _password); + con.setAutoCommit(false); + } + catch(Exception e){} + + return con; + } +} + + +// Implement a sample JDBCIDHandler +class MyIDHandler implements JDBCIDHandler +{ + private static long id = 0; + + public synchronized Object getID() + { + return new Long(++id); + } +} + + diff --git a/contribs/ThomasFenner/code_example1.java b/contribs/ThomasFenner/code_example1.java new file mode 100644 index 0000000000..8d6f7d8c25 --- /dev/null +++ b/contribs/ThomasFenner/code_example1.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Here is a code example to configure the JDBCAppender with a configuration-file + +import org.apache.log4j.*; +import java.sql.*; +import java.lang.*; +import java.util.*; + +public class Log4JTest +{ + // Create a category instance for this class + static Category cat = Category.getInstance(Log4JTest.class.getName()); + + public static void main(String[] args) + { + // Ensure to have all necessary drivers installed ! + try + { + Driver d = (Driver)(Class.forName("oracle.jdbc.driver.OracleDriver").newInstance()); + DriverManager.registerDriver(d); + } + catch(Exception e){} + + // Set the priority which messages have to be logged + cat.setPriority(Priority.INFO); + + // Configuration with configuration-file + PropertyConfigurator.configure("log4jtestprops.txt"); + + // These messages with Priority >= setted priority will be logged to the database. + cat.debug("debug"); //this not, because Priority DEBUG is less than INFO + cat.info("info"); + cat.error("error"); + cat.fatal("fatal"); + } +} + diff --git a/contribs/ThomasFenner/code_example2.java b/contribs/ThomasFenner/code_example2.java new file mode 100644 index 0000000000..40bb71d8c7 --- /dev/null +++ b/contribs/ThomasFenner/code_example2.java @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Here is a code example to configure the JDBCAppender without a configuration-file + +import org.apache.log4j.*; +import java.sql.*; +import java.lang.*; +import java.util.*; + +public class Log4JTest +{ + // Create a category instance for this class + static Category cat = Category.getInstance(Log4JTest.class.getName()); + + public static void main(String[] args) + { + // A JDBCIDHandler + MyIDHandler idhandler = new MyIDHandler(); + + // Ensure to have all necessary drivers installed ! + try + { + Driver d = (Driver)(Class.forName("oracle.jdbc.driver.OracleDriver").newInstance()); + DriverManager.registerDriver(d); + } + catch(Exception e){} + + // Set the priority which messages have to be logged + cat.setPriority(Priority.DEBUG); + + // Create a new instance of JDBCAppender + JDBCAppender ja = new JDBCAppender(); + + // Set options with method setOption() + ja.setOption(JDBCAppender.CONNECTOR_OPTION, "MyConnectionHandler"); + ja.setOption(JDBCAppender.URL_OPTION, "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(COMMUNITY=tcp.world)(PROTOCOL=TCP)(Host=LENZI)(Port=1521))(ADDRESS=(COMMUNITY=tcp.world)(PROTOCOL=TCP)(Host=LENZI)(Port=1526)))(CONNECT_DATA=(SID=LENZI)))"); + ja.setOption(JDBCAppender.USERNAME_OPTION, "mex_pr_dev60"); + ja.setOption(JDBCAppender.PASSWORD_OPTION, "mex_pr_dev60"); + + ja.setOption(JDBCAppender.TABLE_OPTION, "logtest"); + + // There are two ways to setup the column-descriptions : + // 1. Use the the method setOption(JDBCAppender.COLUMNS_OPTION, column-description) + //ja.setOption(JDBCAppender.COLUMNS_OPTION, "id_seq~EMPTY id~ID~MyIDHandler msg~MSG created_on~TIMESTAMP created_by~STATIC~:-) Thomas Fenner (t.fenner@klopotek.de)"); + + // 2. Use the better way of coding with method setLogType(String columnname, int LogType.xxx, Object xxx) + ja.setLogType("id_seq", LogType.EMPTY, ""); + ja.setLogType("id", LogType.ID, idhandler); + ja.setLogType("msg", LogType.MSG, ""); + ja.setLogType("created_on", LogType.TIMESTAMP, ""); + ja.setLogType("created_by", LogType.STATIC, "FEN"); + + // If you just want to perform a static sql-statement, forget about the table- and columns-options, + // and use this one : + //ja.setOption(JDBCAppender.SQL_OPTION, "INSERT INTO LOGTEST (id, msg, created_on, created_by) VALUES (1, @MSG@, sysdate, 'me')"); + + // other options + //ja.setOption(JDBCAppender.BUFFER_OPTION, "1"); + //ja.setOption(JDBCAppender.COMMIT_OPTION, "Y"); + + // Define a layout + //ja.setLayout(new PatternLayout("%m")); + + // Add the appender to a category + cat.addAppender(ja); + + // These messages with Priority >= setted priority will be logged to the database. + cat.debug("debug"); + cat.info("info"); + cat.error("error"); + cat.fatal("fatal"); + } +} + +// Implement a sample JDBCConnectionHandler +class MyConnectionHandler implements JDBCConnectionHandler +{ + Connection con = null; + //Default connection + String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(COMMUNITY=tcp.world)(PROTOCOL=TCP)(Host=LENZI)(Port=1521))(ADDRESS=(COMMUNITY=tcp.world)(PROTOCOL=TCP)(Host=LENZI)(Port=1526)))(CONNECT_DATA=(SID=LENZI)))"; + String username = "mex_pr_dev60"; + String password = "mex_pr_dev60"; + + public Connection getConnection() + { + return getConnection(url, username, password); + } + + public Connection getConnection(String _url, String _username, String _password) + { + try + { + if(con != null && !con.isClosed()) con.close(); + con = DriverManager.getConnection(_url, _username, _password); + con.setAutoCommit(false); + } + catch(Exception e){} + + return con; + } +} + + +// Implement a sample JDBCIDHandler +class MyIDHandler implements JDBCIDHandler +{ + private static long id = 0; + + public synchronized Object getID() + { + return new Long(++id); + } +} + diff --git a/contribs/ThomasFenner/configfile_example.txt b/contribs/ThomasFenner/configfile_example.txt new file mode 100644 index 0000000000..0189a7dc0f --- /dev/null +++ b/contribs/ThomasFenner/configfile_example.txt @@ -0,0 +1,52 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Here is a Configuration-file example, which can be used with the PropertyConfigurator : + + + +# Declare a appender variable named JDBC +log4j.rootCategory=JDBC + +# JDBC is a class of JDBCAppender, which writes messages into a database +log4j.appender.JDBC=JDBCAppender + +# 1. Database-options to connect to the database +log4j.appender.JDBC.url=jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(COMMUNITY=tcp.world)(PROTOCOL=TCP)(Host=LENZI)(Port=1521))(ADDRESS=(COMMUNITY=tcp.world)(PROTOCOL=TCP)(Host=LENZI)(Port=1526)))(CONNECT_DATA=(SID=LENZI))) +log4j.appender.JDBC.username=mex_pr_dev60 +log4j.appender.JDBC.password=mex_pr_dev60 + +# 2. Connector-option to specify your own JDBCConnectionHandler +#log4j.appender.JDBC.connector=MyConnectionHandler + +# 3. SQL-option to specify a static sql-statement which will be performed with every occuring message-event +#log4j.appender.JDBC.sql=INSERT INTO LOGTEST (id, msg, created_on, created_by) VALUES (1, @MSG@, sysdate, 'me') + +# 4. Table-option to specify one table contained by the database +log4j.appender.JDBC.table=logtest + +# 5. Columns-option to describe the important columns of the table (Not nullable columns are mandatory to describe!) +log4j.appender.JDBC.columns=id_seq~EMPTY id~ID~MyIDHandler msg~MSG created_on~TIMESTAMP created_by~STATIC~Thomas Fenner (t.fenner@klopotek.de) + +# 6. Layout-options to define the layout of the messages (optional) +#log4j.appender.JDBC.layout=org.apache.log4j.PatternLayout +#log4j.appender.JDBC.layout.ConversionPattern=%m + +# 7. Buffer-option to define the size of the message-event-buffer (optional) +#log4j.appender.JDBC.buffer=1 + +# 8. Commit-option to define a auto-commitment (optional) +#log4j.appender.JDBC.commit=Y + diff --git a/contribs/VolkerMentzner/HTTPRequestHandler.java b/contribs/VolkerMentzner/HTTPRequestHandler.java new file mode 100644 index 0000000000..d426e86867 --- /dev/null +++ b/contribs/VolkerMentzner/HTTPRequestHandler.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.psibt.framework.net; + +import java.io.*; +import java.net.*; + +/** + * This interface defines all methods that have to be implemented for a HTTPRequestHandler for the + * PluggableHTTPServer. + * + * @author Volker Mentzner + */ +public interface HTTPRequestHandler { + + /** + * Gets the title for html page + */ + public String getTitle(); + + /** + * Sets the title for html page + */ + public void setTitle(String title); + + /** + * Gets the description for html page + */ + public String getDescription(); + + /** + * Sets the description for html page + */ + public void setDescription(String description); + + /** + * Gets the virtual path in the HTTP server that ist handled in this HTTPRequestHandler. + * So the root path handler will return "/" (without brackets) because it handles the path + * "http://servername/" or a handler for "http://servername/somepath/" will return "/somepath/" + * It is important to include the trailing "/" because all HTTPRequestHandler have to serve a path! + */ + public String getHandledPath(); + + /** + * Sets the virtual path in the HTTP server that ist handled in this HTTPRequestHandler. + * So set the path to "/" for the root path handler because it handles the path + * "http://servername/" or set it to "/somepath/" for a handler for "http://servername/somepath/". + * It is important to include the trailing "/" because all HTTPRequestHandler have to serve a path! + */ + public void setHandledPath(String path); + + /** + * Handles the given request and writes the reply to the given out-stream. Every handler has to check + * the request for the right path info. + * + * @param request - client browser request + * @param out - Out stream for sending data to client browser + * @return if the request was handled by this handler : true, else : false + */ + public boolean handleRequest(String request, Writer out); +} \ No newline at end of file diff --git a/contribs/VolkerMentzner/Log4jRequestHandler.java b/contribs/VolkerMentzner/Log4jRequestHandler.java new file mode 100644 index 0000000000..bf231a04d3 --- /dev/null +++ b/contribs/VolkerMentzner/Log4jRequestHandler.java @@ -0,0 +1,177 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.psibt.framework.net; + +import java.io.*; +import java.net.*; +import java.util.*; +import org.apache.log4j.*; + +/** + * This class implements a RequestHandler for log4j configuration. It serves the "/log4j/" path + * in the PluggableHTTPServer. If this path is requested a list of all current log4j categories + * with their current priorities is created. All priority settings can be changed by the user + * and can be submitted and taken over. + * + * @author Volker Mentzner + */ +public class Log4jRequestHandler extends RootRequestHandler { + + private Priority[] prios = Priority.getAllPossiblePriorities(); + + /** + * Creates a new Log4jRequestHandler object + */ + public Log4jRequestHandler() { + this.setTitle("log4j"); + this.setDescription("log4j configuration"); + this.setHandledPath("/log4j/"); + } + + /** + * Handles the given request and writes the reply to the given out-stream. + * + * @param request - client browser request + * @param out - Out stream for sending data to client browser + * @return if the request was handled by this handler : true, else : false + */ + public boolean handleRequest(String request, Writer out) { + String path = ""; + String query = null; + String name; + try { + // check request url + URL url = new URL("http://localhost"+request); + path = url.getPath(); + query = url.getQuery(); + if (path.startsWith(this.getHandledPath()) == false) { + return false; + } + + out.write("HTTP/1.0 200 OK\r\n"); + out.write("Content-type: text/html\r\n\r\n"); + out.write("" + this.getTitle() + "\r\n"); + out.write("

log4j

\r\n"); + out.write(this.getDescription() + "

\r\n"); + + // handle a request with query + if ((query != null) && (query.length() >= 0)) { + StringTokenizer st = new StringTokenizer(query, "&"); + String cmd; + String catname; + String catval; + int idx; + while (st.hasMoreTokens()) { + cmd = st.nextToken(); + idx = cmd.indexOf("="); + catname = cmd.substring(0, idx); + catval = cmd.substring(idx+1, cmd.length()); + if (catname.equalsIgnoreCase("root")) + Category.getRoot().setPriority(Priority.toPriority(catval)); + else + Category.getInstance(catname).setPriority(Priority.toPriority(catval)); + } + } + + // output category information in a form with a simple table + out.write("
"); + out.write("\r\n"); + out.write(" \r\n"); + out.write(" \r\n"); + out.write(" \r\n"); + out.write(" \r\n"); + out.write(" \r\n"); + + // output for root category + Category cat = Category.getRoot(); + out.write(" \r\n"); + out.write(" \r\n"); + out.write(" \r\n"); + out.write(" \r\n"); + + // output for all other categories + for (Enumeration en = Category.getCurrentCategories(); en.hasMoreElements();) { + cat = (Category)en.nextElement(); + out.write(" \r\n"); + out.write(" \r\n"); + out.write(" \r\n"); + out.write(" \r\n"); + out.write(" \r\n"); + } + out.write("
CategoryPriorityAppender
root\r\n"); + out.write(" \r\n"); + out.write(" \r\n"); + for (Enumeration apds = cat.getAllAppenders(); apds.hasMoreElements();) { + Appender apd = (Appender)apds.nextElement(); + name = apd.getName(); + if (name == null) + name = "(no name)"; + out.write(name); + if (apd instanceof AppenderSkeleton) { + try { + AppenderSkeleton apskel = (AppenderSkeleton)apd; + out.write(" [" + apskel.getThreshold().toString() + "]"); + } catch (Exception ex) { + } + } + if (apds.hasMoreElements()) + out.write(", "); + } + out.write("
" + cat.getName() + "\r\n"); + out.write(" \r\n"); + out.write(" \r\n"); + for (Enumeration apds = cat.getAllAppenders(); apds.hasMoreElements();) { + Appender apd = (Appender)apds.nextElement(); + name = apd.getName(); + if (name == null) + name = "(no name)"; + out.write(name); + if (apd instanceof AppenderSkeleton) { + try { + AppenderSkeleton apskel = (AppenderSkeleton)apd; + out.write(" [" + apskel.getThreshold().toString() + "]"); + } catch (Exception ex) { + } + } + if (apds.hasMoreElements()) + out.write(", "); + } + out.write("
\r\n"); + out.write(""); + out.write("
"); + out.write("\r\n"); + out.flush(); + return true; + } catch (Exception ex) { + return false; + } + } +} \ No newline at end of file diff --git a/contribs/VolkerMentzner/PluggableHTTPServer.java b/contribs/VolkerMentzner/PluggableHTTPServer.java new file mode 100644 index 0000000000..12aa063786 --- /dev/null +++ b/contribs/VolkerMentzner/PluggableHTTPServer.java @@ -0,0 +1,262 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.psibt.framework.net; + +import java.net.*; +import java.io.*; +import java.util.*; +import org.apache.log4j.*; + +/** + * This class implements a HTTP-server frame. All HTTP-requests are handled by HTTPRequestHandler + * classes which implement the HTTPRequestHandler interface. Every RequestHandler has + * to be registered in the PluggableHTTPServer with the addRequestHandler method. + * A new thread is created for each connection to handle the request. If all reply data are sent + * to the client the connection is closed and the thread ends. + * An example how to use the PluggableHTTPServer class can be found in the main method + * at the end of the source file. + * + * @author Volker Mentzner + */ +public class PluggableHTTPServer implements Runnable { + + public static final int DEFAULT_PORT = 80; + static Category cat = Category.getInstance("PluggableHTTPServer"); + private int port; + private Vector handler; + private ServerSocket server; + + /** + * Creates a new server object on the given TCP port. + * If the port is occupied by another process a IOException (java.net.BindException) is thrown. + * + * @param port - TCP port number to listen on for requests + */ + public PluggableHTTPServer(int port) throws IOException { + this.port = port; + this.handler = new Vector(); + cat.setPriority(Priority.ERROR); + server = new ServerSocket(this.port); + } + + /** + * Creates a new server object on the default TCP port 80 + * If the port is occupied by another process a IOException (java.net.BindException) is thrown. + */ + public PluggableHTTPServer() throws IOException { + this(DEFAULT_PORT); + } + + /** + * Registers the given HTTPRequestHandler + * + * @param h - the HTTPRequestHandler to register + */ + public void addRequestHandler(HTTPRequestHandler h) { + handler.add(h); + } + + /** + * Unregisters the given HTTPRequestHandler + * + * @param h - the HTTPRequestHandler to unregister + */ + public void removeRequestHandler(HTTPRequestHandler h) { + handler.remove(h); + } + + /** + * Sends the HTTP message 404 - File Not Found + * see RFC2616 for details + * + * @param out - Out stream for sending data to client browser + */ + public static void replyNotFound(Writer out) { + try { + out.write("HTTP/1.0 404 Not Found\r\n"); + out.write("Not Found\r\n"); + out.write("

Not Found

\r\n"); + out.write("\r\n"); + out.flush(); + } // end try + catch (IOException e) { + } + } + + /** + * Sends the HTTP message 405 - Method Not Allowed + * see RFC2616 for details + * + * @param out - Out stream for sending data to client browser + */ + public static void replyMethodNotAllowed(Writer out) { + try { + out.write("HTTP/1.1 405 Method Not Allowed\r\n"); + out.write("Allow: GET, PUT\r\n"); + out.write("Method Not Allowed\r\n"); + out.write("

Method Not Allowed

\r\n"); + out.write("\r\n"); + out.flush(); + } // end try + catch (IOException e) { + } + } + + /** + * Creates the ReplyHTML data for the root page + * + * @param index - index of the RootRequestHandler + */ + public void autoCreateRootPage(int index) { + if (handler.get(index) instanceof RootRequestHandler) { + RootRequestHandler r = (RootRequestHandler)handler.get(index); + String html = ""+r.getTitle()+"\r\n"; + html = html + "

"+r.getDescription()+"

\r\n"; + for (int i = 0; i < handler.size(); i++) { + html = html + "" + ((HTTPRequestHandler)handler.get(i)).getDescription() + "
"; + } + html = html + "\r\n"; + r.setReplyHTML(html); + } + } + + /** + * Main loop of the PluggableHTTPServer + */ + public void run() { + while (true) { + try { + Socket s = server.accept(); + Thread t = new ServerThread(s); + t.start(); + } + catch (IOException e) { + } + } + } + + /** + * This class handles the incomming connection for one request. + */ + class ServerThread extends Thread { + + private Socket connection; + + ServerThread(Socket s) { + this.connection = s; + } + + /** + * Serves the HTTP request. + */ + public void run() { + try { + Writer out = new BufferedWriter( + new OutputStreamWriter( + connection.getOutputStream(), "ASCII" + ) + ); + Reader in = new InputStreamReader( + new BufferedInputStream( + connection.getInputStream() + ) + ); + + // read the first line only; that's all we need + StringBuffer req = new StringBuffer(80); + while (true) { + int c = in.read(); + if (c == '\r' || c == '\n' || c == -1) break; + req.append((char) c); + } + String get = req.toString(); + cat.debug(get); + StringTokenizer st = new StringTokenizer(get); + String method = st.nextToken(); + String request = st.nextToken(); + String version = st.nextToken(); + + if (method.equalsIgnoreCase("GET")) { + boolean served = false; + for (int i = 0; i < handler.size(); i++) { + if (handler.get(i) instanceof HTTPRequestHandler) { + if (((HTTPRequestHandler)handler.get(i)).handleRequest(request, out)) { + served = true; + break; + } + } + } + if (!served) + PluggableHTTPServer.replyNotFound(out); + } + else { + PluggableHTTPServer.replyMethodNotAllowed(out); + } + } // end try + catch (IOException e) { + } + finally { + try { + if (connection != null) connection.close(); + } + catch (IOException e) {} + } + } // end run + } // end class ServerThread + + /** + * Demo how to use the PluggableHTTPServer. + */ + public static void main(String[] args) { + + int thePort; + + // create some logging stuff + BasicConfigurator.configure(); + Category cat1 = Category.getInstance("cat1"); + cat1.addAppender(new org.apache.log4j.ConsoleAppender(new PatternLayout("%m%n"))); + Category cat2 = Category.getInstance("cat2"); + cat2.setPriority(Priority.INFO); + cat2.addAppender(new org.apache.log4j.ConsoleAppender(new PatternLayout("%c - %m%n"))); + + // set TCP port number + try { + thePort = Integer.parseInt(args[1]); + } + catch (Exception e) { + thePort = PluggableHTTPServer.DEFAULT_PORT; + } + + PluggableHTTPServer server = null; + while (server == null) { + try { + server = new PluggableHTTPServer(thePort); + server.addRequestHandler(new RootRequestHandler()); + server.addRequestHandler(new Log4jRequestHandler()); + server.addRequestHandler(new UserDialogRequestHandler()); + server.autoCreateRootPage(0); + Thread t = new Thread(server); + t.start(); + } catch (IOException e) { + server = null; + thePort++; + } + } + + } // end main +} diff --git a/contribs/VolkerMentzner/RootRequestHandler.java b/contribs/VolkerMentzner/RootRequestHandler.java new file mode 100644 index 0000000000..121d39b0e3 --- /dev/null +++ b/contribs/VolkerMentzner/RootRequestHandler.java @@ -0,0 +1,159 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.psibt.framework.net; + +import java.io.*; +import java.net.*; +import java.util.*; + +/** + * This class implements a RequestHandler for the root path "/" in the PluggableHTTPServer. + * A simple HTML message will be replied to the client. + * + * @author Volker Mentzner + */ +public class RootRequestHandler implements HTTPRequestHandler { + + private String title; + private String description; + private String handledPath; + private String ReplyType = "Content-type: text/html\r\n\r\n"; + private String ReplyHTML = "Root\r\n" + + "

Root

\r\n" + + "\r\n"; + + /** + * Creates a new RootRequestHandler object + */ + public RootRequestHandler() { + this.setTitle("root page"); + this.setDescription("root page"); + this.setHandledPath("/"); + } + + /** + * Gets the content type of the reply HTTP message + * + * @return content type as String + */ + public String getReplyType() { + return this.ReplyType; + } + + /** + * Sets the content type of the reply HTTP message + * + * @param ReplyType - content type as String + */ + public void setReplyType(String ReplyType) { + this.ReplyType = ReplyType; + } + + /** + * Gets the HTML data of the reply HTTP message + * + * @return HTML message as String + */ + public String getReplyHTML() { + return this.ReplyHTML; + } + + /** + * Sets the HTML data of the reply HTTP message + * + * @param ReplyHTML - HTML message as String + */ + public void setReplyHTML(String ReplyHTML) { + this.ReplyHTML = ReplyHTML; + } + + /** + * Gets the title for html page + */ + public String getTitle() { + return this.title; + } + + /** + * Sets the title for html page + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * Gets the description for html page + */ + public String getDescription() { + return this.description; + } + + /** + * Sets the description for html page + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * Gets the server path + * + * @return the server path + */ + public String getHandledPath() { + return this.handledPath; + } + + /** + * Sets the server path + * + * @param path - the server path + */ + public void setHandledPath(String path) { + this.handledPath = path; + } + + /** + * Handles the given request and writes the reply to the given out-stream. + * + * @param request - client browser request + * @param out - Out stream for sending data to client browser + * @return if the request was handled by this handler : true, else : false + */ + public boolean handleRequest(String request, Writer out) { + String path = ""; + String query = null; + try { + URL url = new URL("http://localhost"+request); + path = url.getPath(); + query = url.getPath(); + if (path.equals(handledPath) == false) { + return false; + } + + out.write("HTTP/1.0 200 OK\r\n"); + if (ReplyType != null) + out.write(ReplyType); + if (ReplyHTML != null) + out.write(ReplyHTML); + out.flush(); + return true; + } catch (Exception ex) { + return false; + } + } +} \ No newline at end of file diff --git a/contribs/VolkerMentzner/UserDialogRequestHandler.java b/contribs/VolkerMentzner/UserDialogRequestHandler.java new file mode 100644 index 0000000000..4a5124dd8b --- /dev/null +++ b/contribs/VolkerMentzner/UserDialogRequestHandler.java @@ -0,0 +1,135 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Title: PSI Java Framework: UserDialogRequestHandler

+ * Copyright: PSI-BT AG

+ * History: + * Date Author What's new + * 16.04.2001 VMentzner Created + */ + +package com.psibt.framework.net; +/** + * This class implements a RequestHandler for the path "/userdialog/" in the PluggableHTTPServer. + * A simple input form is presented in the browser where you can enter a message. This message will be sent + * to the PluggableHTTPServer and shown in a JOptionPane MessageDialog. + * + * @author Volker Mentzner + */ +public class UserDialogRequestHandler extends RootRequestHandler { + + private Component parentComponent; + + /** + * Creates a new UserDialogRequestHandler object + */ + public UserDialogRequestHandler() { + this(null); + } + + /** + * Creates a new UserDialogRequestHandler object with a parentComponent reference + */ + public UserDialogRequestHandler(Component parentComponent) { + this.setTitle("user dialog"); + this.setDescription("show user dialog"); + this.setHandledPath("/userdialog/"); + this.parentComponent = parentComponent; + } + + /** + * Handles the given request and writes the reply to the given out-stream. + * + * @param request - client browser request + * @param out - Out stream for sending data to client browser + * @return if the request was handled by this handler : true, else : false + */ + public boolean handleRequest(String request, Writer out) { + String path = ""; + String query = null; + try { + URL url = new URL("http://localhost"+request); + path = url.getPath(); + query = url.getQuery(); + if (path.startsWith(this.getHandledPath()) == false) { + return false; + } + + out.write("HTTP/1.0 200 OK\r\n"); + out.write("Content-type: text/html\r\n\r\n"); + out.write("" + this.getTitle() + "\r\n"); + out.write("

" + this.getDescription() + "

\r\n"); + if ((query != null) && (query.length() >= 0)) { + int idx = query.indexOf("="); + String message = query.substring(idx+1, query.length()); + // replace '+' by space + message = message.replace('+', ' '); + // replace hex strings starting with '%' by their values + idx = message.indexOf("%"); + while (idx >= 0) { + String sl = message.substring(0, idx); + String sm = message.substring(idx+1, idx+3); + String sr = message.substring(idx+3, message.length()); + try { + int i = Integer.parseInt(sm, 16); + sm = String.valueOf((char)i); + } + catch (Exception ex) { + sm = ""; + } + message = sl + sm + sr; + idx = message.indexOf("%"); + } + // show message in a new thread + if ((message != null) && (message.length() > 0)) { + Thread t = new Thread(new DialogThread(parentComponent, message)); + t.start(); + } + } + out.write("
"); + out.write("\r\n"); + out.write(" \r\n"); + out.write(" \r\n"); + out.write("
Send message to user
\r\n"); + out.write(""); + out.write("
"); + out.write("\r\n"); + out.flush(); + return true; + } catch (Exception ex) { + return false; + } + } + + /** + * Internal class to start the user dialog in a new thread. This makes the RequestHandler return + * immediatly + */ + class DialogThread implements Runnable { + private Component parentComponent; + private String message; + + public DialogThread(Component parentComponent, String message) { + this.parentComponent = parentComponent; + this.message = message; + } + + public void run() { + JOptionPane.showMessageDialog(parentComponent, message); + } + } +} \ No newline at end of file diff --git a/contribs/VolkerMentzner/mail-03-05-2001 b/contribs/VolkerMentzner/mail-03-05-2001 new file mode 100644 index 0000000000..f69433351c --- /dev/null +++ b/contribs/VolkerMentzner/mail-03-05-2001 @@ -0,0 +1,42 @@ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + + +Delivered-To: cgu@qos.ch +From: "Mentzner, Volker" +To: "'cgu@qos.ch'" +Subject: Remote configuring log4j +Date: Thu, 3 May 2001 08:10:25 +0200 +X-Mailer: Internet Mail Service (5.5.2653.19) + +Hi Ceki, + +I am using log4j in a GUI project. Working at the application I found +it useful to remotely configure log4j with my favourite browser. This +is reached by using a very small web server (PluggableHTTPServer) with +extentions for tasks like configuring log4j. You can easily put this +web server in an application, an example can be found in +PluggableHTTPServer.main(). Maybe someone else can use this too, so I +sent it to you to give it to the contrib dir if you like it. + +Regards + + +Volker Mentzner + + <> + diff --git a/doap_log4j.rdf b/doap_log4j.rdf new file mode 100644 index 0000000000..1c314c30bf --- /dev/null +++ b/doap_log4j.rdf @@ -0,0 +1,51 @@ + + + + + + 2007-02-09 + + Apache log4j + + + Apache log4j provides logging services for Java. + + + + Java + + + + Apache log4j 1.2.17 + 2012-05-06 + 1.2.17 + + + + + + + + + + diff --git a/docs/HISTORY.txt b/docs/HISTORY.txt deleted file mode 100644 index c6ebadf465..0000000000 --- a/docs/HISTORY.txt +++ /dev/null @@ -1,1941 +0,0 @@ - - - [*] Changes that are 100% compatible with existing client code. - [**] Changes that requiring little or no modification to existing - client code. - [***] Changes requiring important modifications to existing client code. - - [D] Changes affect a method or property which was previously marked as - deprecated. - - - Release of version 1.3-alpha-9 - Release date: TBD - - - Cleaned up FileWatchdog implementation. - - January 30th, 2006 - - Release of version 1.3alpha-8 - - - Bugs 35452, 37965, 38304, 38395, 37740: Substantial modifications to restore - binary compatibility with log4j 1.2.xx. Restored NTEventLogAppender, - org.apache.log4j.jmx classes, org.apache.log4j.varia filters and - org.apache.log4j.helpers date formats. (Please note that the - NTEventLogAppender dll is not packaged with this release, but the build - target (build.nt.dll) is available to build it locally if needed. The next - release will contain the build dll.) - - - Bug 38394: enhanced diagnostic message on configuration errors. - - - Bug 38304: fixed incorrect error message if console appender - used during configuration is missing at cleanup. - - - Bug 38104: Consolidated locations of generated files. - - - Bug 37864: Generation of binary compatibility report. - - - Bug 37960: Updated documentation generation to use Velocity 1.4 and - eliminated dependency on logging-site module. - - - Bug 38406: Removed inadvertent JDK 1.4 dependencies. - - - Removed org.apache.log4j.watchdog.TimedURLWatchdog in favor of - org.apache.log4j.watchdog.TimedLocationWatchdog. TimedLocationWatchdog is - more generic in that is uses a String to describe the location instead of a - URL. FileWatchdog inherits from this class and the future HttpWatchdog will - as well. - - October 12th, 2005 - - Release of version 1.3alpha-7 - - - Added target="1.2" and source="1.3" attributes to all usages of - to make sure that classes are compatible with JDK1.2+ no matter the JDK - under which the compilation is done. This mirrors what was done to the - 1.2 branch while taking into account usage of JDK1.2 features where the - 1.2 branch needs to stay compatible with JDK1.1. [*] - - - Added back org.apache.log4j.spi.ErrorHandler and its implementations to - help make 1.3 binary compatible with 1.2.xx. Implementations are all NOP - and clearly marked as deprecated in the Javadoc. Same goes for get/set - methods for error handlers in appenders. This change allows applications - such as LogWeb, which make heavy use of Log4j internals, to compile and - run against Log4j-1.3 where it was only compatible with 1.2.xx - previously. [*] - - - Made private "next" variable in org.apache.log4j.spi.Filter public to - make it binary-compatible with the 1.2 branch. Also marked it as - deprecated (which I also did for the 1.2.12 release) [*] - - - Chatty output about Logger creation or retrieval events is now - suppressed by default. They can be enabled by explicitly setting the - log4j.coreDebug system property. [*] - - - The log4j.debug system property no longer has any affect as all - log4j output is done through regular Logger objects. However, in - configuration file in properties format, the log4j.debug property will - cause PropertyConfigurator to *temporarily* output logs generated - during the configuration process. This is very similar to the way the - debug attribute works in configuration files in XML format. [*] - - - Fixed bug 35965 by adding protected accessors for member variables - topicConnection, topicSession, and topicPublisher. [*] - - - Fixed Bugzilla 14551, misplaces sample.xml links in JavaDocs. - http://issues.apache.org/bugzilla/show_bug.cgi?id=14551 [*] - - - Closed Bugzilla 34162, log4j-db.jar built empty, which had been - previously fixed. - http://issues.apache.org/bugzilla/show_bug.cgi?id=34162 [*] - - - Closed Bugzilla 34163, missing chainsaw module in xdocs/install-chainsaw.xml, - which had been previously fixed. - http://issues.apache.org/bugzilla/show_bug.cgi?id=34163 [*] - - - Fixed Bugzilla 30853: made System.out printing conditional upon - log4j.debug system property. [*] - - - Fixed Bugzilla 30623, better JavaDoc for DailyRollingFileAppender#getDatePattern. - http://issues.apache.org/bugzilla/show_bug.cgi?id=30623 [*] - - - Fixed Bugzilla 34747: DBAppender reused Statement objects inappropriately. - http://issues.apache.org/bugzilla/show_bug.cgi?id=34747 [*] - - - Fixed Bugzilla 35324: VectorWriter#println NPE on null argument. - http://issues.apache.org/bugzilla/show_bug.cgi?id=35324 [*] - - - January 20th, 2005 - - Release of version 1.3alpha-6 - - - Fixed involuntary omission of DOMConfigrator (deprecated) in log4j-VERSION.jar. - - Added missing files in log4-oro.jar. - - The lengthy system property "log4j.repositorySelectorClass" was renamed as - "log4j.repositorySelector". - - January 19th, 2005 - - Release of version 1.3alpha-5 - - - Universal and Generic Logging Interface (UGLI) is now part of log4j. - UGLI allows variation in the logging API implementattion in a simple and - robust way. Log4j directly supports the interfaces defined by UGLI. - For more information see http://logging.apache.org/log4j/docs/ugli.html [*] - - - Log4j now ships with several jar files, one jar file per dependency. [*/**] - - - Fixed Bugzilla 15198: TelnetAppender: NullPointerException if - SocketHandler not initialized. [*] - - - Fixed Bugzilla 12112: CountingQuietWriter miscounts bytes. [*] - - - Fixed Bugzilla 18076: setting of firstTime in OnlyOnceErrorHandler. [*] - - - Added pattern conversion support for the Subject line for emails - generated by SMTPAppender. The set of patterns is the same as those - supported by PatternLayout. [*] - - - Implemented Bugzilla 20985: charset support for SMTPAppender [**] - - - Implemented Bugzilla 20500: separate registry clearing from doConfigure in PropertyConfigurator - to allow to easier extension. [*] - - - Fixed Bugzilla 23912: unsafe access to BoundedFIFO in AsyncAppender. [*] - - - Changed converter register accessors in PatternParser to take/return Map instead - of HashMap, a cleaner abstraction allowing for different implementation types. [*] - - - Fixed Bugzilla 26658: modify build.xml chainsaw target with respect to crimson.jar [*] - - - Fixed Bugzilla 28682: NullPointerException in SocketHubAppender#cleanup. [*] - - - Fixed Bugzilla 28464: White space significant at end of line for PropertyConfigurator. [*] - - - Fixed Bugzilla 26117: Output encoding for TelnetAppender. [*] - - November 25, 2004 - - - Release of version 1.3alpha-3 - - - Classes are built with the javac debug setting on. - - Fixed unset activeFile bug in SlidingWindowRollingPolicy. - - November 25, 2004 - - - Release of version 1.3alpha-2 - - - The deprecated DOMConfigrator was mistakenly left as the default - configrator for XML files. This has been fixed and JoranConfigrator - now is the default configrator for XML files. - - November 24th, 2004 - - - Release of version 1.3alpha-1 - - - Log4j now uses itself for its own logging. For more details refer to - - http://www.qos.ch//logging/internalLogging.jsp - - - The Appender.requiresLayout() method is no longer needed. - - This method was only used by PropertConfigrurator and not - DOMConfigurator nor JoranConfigurator. It was never strictly necessary - and case the layout is *optional* for a given appender type, it causes - unwarranted error messages. - - This simplification will make it slightly easier to write appenders. - - - Added new printing methods message supporiting pattern parsing. These new forms - avoid superflous parameter construction and yield a significant performance - increase in the case of disavled log statements. [*] - - - Added new ListAppender & ListModelAppender classes to the org.apache.log4j.varia package. - These are rather simplistic Appender implementations that store LoggingEvents in - an internal buffer (java.util.List and a DefaultListModel respectively) which can - be useful in certain applications (such as a Swing GUI app etc). [*] - - - org.apache.log4j.HTMLLayout has been replaced with org.apache.log4j.html.HTMLLayout. - The new HTMLLayout admits a conversion pattern using the same syntax as - PatternLayout. Thus, the user can customize the content of columns in the HTML table - produced by HTMLLayout. Just as importantly, many visual aspects of the table can be - customized at row or even cell level with the help of a CSS file. - - The new HTMLLayout has been contributed by Steve Mactaggart. - - - Log4j now ships with JoranConfigurator, a powerful replacement for - DOMConfigurator. Joran bring a plethora of new capabilities. In - particular, it can be taught new parsing rules on the fly, even from - within the config file being processed. Moreover, with the help of - implicit actions, it can configure specialized sub-components of log4j - components. - - Many of the new components in version 1.3 can be configured thanks - to the new capabilitues found in JoranConfigurator. - - - Fixed bug #15585 relative to location information extraction on the AS400. The fix - was contributed by Patrice Kolata. [*] - - - Log4j will now automatically include stack traces for nested - exceptions. Log4j extends the automatic nested exception printing - available in JDK 1.4 to nested exceptions accessible through methods - named "getRootCause", "getNextException" and "getException", not just - "getCause" as in JDK 1.4. [*] - - - The location information extraction code has been refactored to use - a faster mechanism when running on JDK 1.4 or later. The new mechanism, contributed - by Martin Schulz, is at least twice as fast. - - See http://marc.theaimsgroup.com/?t=108473346700001&r=1&w=2 for more details. [*] - - - Made ignoresThrowable a settable property. The user can now force a layout - to ignore the throwable in the event even if the layout knows how to handle - exceptions. Conversely, an appender can be fooled to believe that a layout - handled the exception in the logging event by setting a layout's ignoresThrowable - property to false. [*] - - - The org.apache.log4j.db package replaces the old org.apache.log4j.jdbc - package. The new package supports most relational database systems - such as PostgreSQL, MySQL, Oracle, DB2 or MsSQL. It can also handle - retrieve connections using a JDBC driver class, a data source class or - JNDI. [*] - - - A sequenceNumber field has been added to LoggingEvent. This fields is useful when - checking for the equality of two logging events or when ordering them. [*] - - - Log4j now has its own Scheduler. It allows jobs to be executed at a certain date - or even periodically. It only requires just one extra thread. [*] - - - Added the "isPristine" flag to LoggerRepository. As soon as a configurator - starts configuring a repository this flag is set to false. - - - Removed support for the deprecated property "log4j.configDebug". [**/D] - - - The new ContextJNDISelector allows for the possibility of managing - multiple logger hiearchies within the same application server while - only a single copy of log4j.jar is present in memory. - - - Added keys() method to the MDC class as requested by Don Isenor. - - - Certain operations on Loggers are now made using ReaderWriterLocks which - allows simultaneous read operations but only one write operation. This should - significantly improve logging throughput in heavily loaded server environments. - - - Rolling can now be triggered based on time or size as was already the case in - log4j 1.2. However, the new architecture allows for much more variation in the - timing of the rollover and the actions taken during rollover (i.e on the fly - compression, renaming, moving). The new architecture was suggested a long time - ago by James P. Cakalic. A similar design can be found in the Avalon Logkit - package. - - In order to avoid duplication, the old org.apache.log4j.RollingAppender - and org.apache.log4j.RollingAppender classes have been removed. [**] - - - LoggingEvent was extended to allow properties. Properties are meant to be set - by Layout and Appender classes as they output/process logging events. - Properties are per logging event where MDC values are per thread. - - - Another LoggingEvent constructor was added to allow instances to be reconstituted - when received from remote sources that do not use LoggingEvent as the transport - type (like XML for example). - - - Fixed bug #23096. NullAppender getInstance method is now declared as a static. - - - Fixed bug #10706. The %X pattern without a key no longer causes a NullPointer - exception, - - - ADD: LIST OF CHAINSAW IMPROVEMENTS. - - November 2nd, 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 - 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 - - - Fixed bug #8527. A closed TelnetAppender would continue waiting - for connections even if its ServerSocket was closed. This caused - the TelnetSocket to sit in a loop and complain about the closed - socket. [*] - - - AsyncAppender throws NullPointerException problem. The bug was actually in - AppenderSkeleton. See bug #5444 details. [*] - - - Added support for recursive variable substiuton as requested by - Eric Chastan. [*] - - - SocketNode now used a BufferedInputStream as suggested by Kok Chong - in bug report #3933. [*] - - - Fixed a problem with DailiyRollingAppender which would not - correctly compute the rollover period in certain timezones. See bug - report #7550. [*] - - - Fixed documentation bug #2726 in FAQ.html. [*] - - - In WriterAppender, fixed bug #2383 by adding a flush statement in the - writeFooter method. [*] - - - In XMLLayout, Fixed bug #7550 by escaping the method attribute. The - XMLLayout also outputs each item of a stack trace in a separate - line. [*] - - - Fixed bug #5932 as suggested by Heikki Linnakangas. The - LoggingEvent.getMDCCopy method now clones the MDC instead of just - referencing it. [*] - - (rc1) - - - The ANT build script was modified to use jar files specified in - the build.properties file instead of the CLASSPATH environment - variable. The build.properties file depends on local paths and is - supplied by the user. The build.properties.sample file is included - in the distribution. The build.sh and build.bat scripts have - been removed. This is the way many other jakarta projects build their - projects. The jar files in the dist/lib directory were also removed - since they are no longer used. [*] - - - The DOMConfigurator now interprets the string after the '#' - character in the value attribute within the element as - the fully qualified class name of a custom Level. This is consistent - with the way log4j handles "level" values in other places. The - class attribute is still honored. [*] - - - Added Oliver Burn's chainsaw tool to the core log4j - distribution. Visualisation and dynamic filtering of log events is - bound to be a very important area of activity in the future. [*] - - - Added the org.apache.log4j.jdbc.JDBCAppender which as the name - indicates sends events to a database using the JDBC API. Thanks to - Kevin Steppe for supplying the code. [*] - - - Added SocketHubAppender class as contributed by Mark Womack. This - appender sends LoggingEvent objects to a set of remote a log - servers. [*] - - - In the Category class, the getChainedPriority method has been - replaced with getEffectiveLevel method. [*] - - (beta4) - - - Replaced the custom class loading based on the thread context class - loader with a simple Class.forName() call. This solves two allied - but distinct problems encountered when using Ant with JUnit - although the bug is more general. In one instance of the - problem, log4j would throw java.lang.NoClassDefFoundError for - org/apache/log4j/AppenderSkeleton where log4j.jar and related - classes were clearly available to the Ant classloader. In another - incarnation, log4j would reject a custom appender claiming that it is - not assignable to a org.apache.log4j.Appender variable. This would - occur when log4j.jar was available to both the Ant classloader and the - system classloader. - - Thanks to Dave Herman for providing detailed scenarios exposing - the issues involved. See - http://forum.java.sun.com/thread.jsp?forum=38&thread=70946 - http://forum.java.sun.com/thread.jsp?forum=38&thread=70946#479697 - http://marc.theaimsgroup.com/?l=ant-user&m=101139178705895&w=2 - for more details. [*] - - - (beta3) - - - Fixed the complaints the compiler issued when using the - Logger.setLevel() methd. [*] - - - Incorporated the performance enhancements to ISO8601DateFormat and - AbsoluteTimeDateFormat classes submitted by Andrew Vajoczki. - - (beta2) - - - Source code written for log4j 1.1.3.jar will compile fine with - log4j 1.2X. However, code compiled for log4j 1.1.3 would previously - systematically throw "java.lang.NoSuchMethodError" runtime exceptions - when run with log4j 1.2 - prior to beta2. This problem has been - corrected in beta2. Pheew, that was a close one. [*] - - - Log4j 1.2 is now backward compatible in serialization of - LoggingEvents. For example, a 1.1.3 SocketAppedner can write to 1.2 - SocketServer. Similarly a 1.2 JMSAppender will work with 1.1.3 - JMSSink. This should ease the move to log4j 1.2, especially in - large deployments. [*] - - (alpha7) - - - The src/java/org/apache/log4j/examples/ directory moved under the - top-level directory as examples/. [*] - - - Fixed the ArrayIndexOutOfBoundsException that was thrown by - AsyncAppender if multiple threads were trying to log an event - containing an exception near simultaneously. Thanks to Thomas Tuft Muller - for reporting this bug. [*] - - (alpha1-alpha6) - - - Improved error reporting in DOMConfigurator. Thanks to Thomas Tuft - Muller for contributing the enhancement. [*] - - - Log4j is now configurable using JMX. JMX support is not of - production quality. [*] - - - Added support for different encodings in WriterAppender. Thanks to - Ben Sandee for submitting the relevant patch. [*] - - - Modified SMTPAppender to allow multiple email sessions. Thanks to - Jon Skeet for supplying the relevant patch. [*] - - - The CategoryFactory class has been replaced by the LoggerFactory - class. The makeNewCategoryInstance method has been renamed as - makeNewLoggerInstance. This change requires subclasses of Category - classes to be modified and recompiled. [**] - - - The Level class replaced the Priority class. Priority class now - extends Level to preserve backward compatibility. [*] - - - The Logger class replaced the Category class. Logger class - extends Category to preserve backward compatibility. We proudly - mark this change with a single star for 100% compatibility. [*] - - - The Category.assert method has been replaced by - Category.assertLog. This change was necessary because assert is a - language reserved word in JDK 1.4. [*/**] - - - Removed deprecated methods setOptions and getOptionStrings defined - in the org.apache.log4j.spi.OptionHandler interface. This interface - is implemented by most log4j appenders and layouts. In particular, - all appenders and layouts shipped with log4j contain these - deprecated methods. They have become totally redundant after we - moved to JavaBeans style configuration in log4j 1.1. [**] - - - The disable(Level) methods in Hierarchy have been removed and been - replaced by threshold methods. [**] - - - Added buffered IO capability to FileAppender and subclasses. [*] - - - The location information (or stack information) was not correctly - transmitted by JMSAppender. [*] - - - Added event reporting capability to the Hierarchy class. - - - Added new system property "log4j.configuratorClass". This property - allows the user to specify the custom configurator at the default - initialization phase. This property replaces the previous - interpretation of the reference part of "log4j.configuration" - as the custom configurator class. This interpretation was sometimes - erroneous and caused headaches. [*] - - - Introduced the Mapped Diagnostic Context or MDC class. This class - is similar to the NDC except that the diagnostic context is based - on a map instead of a stack. Moreover the MDC is automatically - inherited by child threads under JDK 1.2 and above. [*] - - - Corrected a performance bug in the NDC class as observed by Dan - Milstein and independently by Ray Millard. [*] - - - Removed deprecated methods disable(Priority), disableAll, - disableDebug, disableInfo and enableAll in BasicConfigurator. [*] - - - Added supports java.io.Reader objects in the method doConfigure(), - instead of only InputStream. Thanks to Mark Womack for submitting - the relevant patch. [*] - - - Corrected the restart bug in DayliRollingFileAppender. Thanks to - Jim Moore for supplying the relevant patch. [*] - - June 19, 2001 - - - Release of version 1.1.3 - - - Added a missing namespace declaration in the log4j:configuration - element in log4j.dtd. The missing declaration caused the new - generation of namespace aware parsers to barf when parsing log4j - configuration files. [*] - - - Reduced the size of log4j-core.jar to 78KB. [*] - - - Minor documentation changes. [*] - - June 7, 2001 - - - Release of version 1.1.2 - - - Corrected a problem with the static initializer of the Category - class which would use the wrong class loader to search for the - default configuration file. The associated search algorithm has - been also simplified. Nevertheless, the preferred method to specify - the automatic configuration file is by setting the - log4j.configuration system property. [*] - - - Documentation improvements. Added a new section to the manual - explaining the default initialization procedure [*] - - - Enhancements to the org.apache.log4j.examples.appserver package. [*] - - - Corrected a bug in the way the NTEventLogAppender printed - exceptions. [*] - - May 20, 2001 - - - Release of version 1.1.1. - - - Added missing custom priority support in PropertyConfigurator. [*] - - - Made a number of fields protected instead of default access in - SMTPAppender. [*] - - May 19, 2001 - - - Release of version 1.1. - - - This release has the same code as 1.1b7. It differs only in a few minor - documentation changes. - - May 9, 2001 - - - Release of version 1.1b7 - - - Made BasicConfigurator disable methods static as they were in log4j - 1.0.4. Thanks to Francisco Marin for reporting the bug. [*] - - - Corrected a two related deadlock problems introduced while fixing - bug 1505. Thanks to joelr@viair.com for reporting the problem. [*] - - - The configureAndWatch methods in Configurators did not close the - configuration file, preventing its editing. See bug 1686. [*] - - - In DOMConfigurator.setParameter special character conversion now - precedes variable substitution. This change was suggested by Steven - Velez. The vast majority of users should be oblivious to it. [*] - - - The TextPaneAppender is no longer maintained and has been - removed. It is still available under the contribs/ - directory. This change has been discussed in the log4j mailing - lists and no one objected to the removal of the TextPaneAppender - class. - - April 26, 2001 - - - Release of version 1.1b6 - - - Aaron Greenhouse from Carnegie Mellon SCS found a series of - multi-threading related bugs in Category and AsyncAppender. See bug - ids 1505 and 1507 in our bug database for exemplary bug - reports. They are worth the detour. [*] - - - InvalidJarIndexException is only available in JDK 1.3. Referring - to this exception type caused log4j 1.1b5 to break on earlier JDKs. - We now avoid referring to it. [*] - - - Added PriorityRangeFilter by Simon Kitching. See the Threshold - option in AppenderSkeleton for a more convenient alternative. [*] - - April 22, 2001 - - - Release of version 1.1b5 - - - In HTMLLayout, the Title option sets the HTML document - title (...<title>). [*] - - - Corrected an important performance bug in LocationInfo. Hein Couwet - and kr@it-practice.dk have independently identified the bug. This is - yet another example of the difference made by the number of eyeballs - studying source code. [*] - - - Corrected the incorrect value returned by LocationInfo.getClassName - method when running under IBM Visual Age. Thanks to Mathias - Rupprecht for supplying the relevant patch. [*] - - - Corrected a bug where the build.sh file in the distribution would be in - DOS CRLF format. Thanks to ma.darche@free.fr for reporting the - problem. [*] - - - Corrected InvalidJarIndexException thrown in applets while - searching for the default log4j configuration file. Thanks to - Michael Lundahl for reporting this bug. [*] - - - Added missing PropertySetterException class to log4j-core.jar. - Thanks to ma.darche@free.fr for reporting this bug. [*] - - April 20, 2001 - - - Release of version 1.1b4 - - - Mathias Bogaert observed that in version 1.1b3 the search algorithm - for the resource used in automatic log4j configuration was - different than in 1.0.x. Beta4 uses a more powerful mechanism which - is also compatible with 1.0.x. [*] - - - Paul Glezen correctly observed that if log4j is deployed in a - client/server mode where multiple log4j clients log to a log4j - server, all hosts must be upgraded to version 1.1 in one go because - the internal LoggingEvent class used in client/server communication - changed in log4j 1.1. - - April 18, 2001 - - - Release of version 1.1b3 - - - Added a RollingFileAppenderBeanInfo class that fakes the - maxFileSize JavaBeans property as a String type instead of a long. - This allows us to resuscitate setMaxFileSize(long) method that was - removed in 1.1b2 breaking 100% backward compatibility. This addition - restores 100% backward compatibility. [*] - - April 18, 2001 - - - Release of version 1.1b2 - - - The directory structure has changed to better suit Jakarta - conventions as follows: - - org/** --> src/java/org/** - xdocs/** --> src/xdocs/** - - If you have a CVS checked out copy of log4j be sure to check out a - fresh copy. [*] - - - Added a few jar files required at build time to build/lib so that - it is now possible to compile log4j out of the box. [*] - - - Whenever a priority parameter is expected in a configuration file, - one can now use a custom priority class. See OptionConverter.toPriority - method for more information. Note that the <priority> element in - log4j.dtd remains unaffected by this change. [*] - - - Added the setQuietMode(boolean) method to LogLog. In quiet mode - LogLog will not output anything even in case of errors. [*] - - - Log4j components are now configured as JavaBeans. The setOption and - getOptionString methods have been deprecated in OptionHandler - interface which is implemented by most log4j components. [*] - - - The stack trace of a throwable passed in a logging statement is not - parsed into a stack array which is serializable. This allows cascading of - log4j servers to properly propagate throwable information. [*] - - - In XML configuration files, the <configuration> element has been - deprecated and was replaced by the <log4j:configuration> element. [*] - - The following perl command can help to migrate: - - perl -p -i.bak -e "s/configuration/log4j:configuration/;" file1.xml .. fileN.xml - - - The "log4j.configDebug" system property has been replaced with the - "log4j.debug" system property although it is still available. - Similarly, the "configDebug" attribute has been deprecated and - replaced with the "debug" attribute in log4j.dtd. [*] - - - February 23, 2001 - - - Release of version 1.1b1 - - - Logging can now be disabled per Hierarchy. It can also be disabled - using configuration files using the "disable" directive. The - "disableOverride" directive takes precedence over the "disable" - directive. As a result of this change the disable family of - methods in BasicConfigurator has been deprecated and replaced by the same - family of methods in the Hierarchy class. [*] - - - The FileAppender has been split into three parts: WriterAppender, - ConsoleAppender and FileAppender. ConsoleAppender takes over the - console logging functionality of FileAppender. As a result support - for stream and console printing has been deprecated in FileAppender. [**] - - - The FileAppender now correctly outputs the header and footer of its - layout. This problem was reported by too many users to list here. [*] - - - Appenders and Layouts now get to see the raw message object in - LoggingEvent not just its rendered form. The access modifiers of - some LoggingEvent fields were changed so that they can be accessed - in less error-prone ways. Thanks to Jim Cakalic and Anders Kristens - for their valuable advice. [*] - - - Added getLayout(), getErrorHandler(), and getFilter() to the - Appender interface. [*] - - - Added getOption(key) method to the OptionHandler interface and modified - implementations of it as appropriate. [*] - - - Added the much awaited DailyRollingFileAppender. [*] - - - The structure of the distribution changed somewhat. The log4j.jar - files can be found under dist/. The javadoc directory has been - moved to docs/api/. We are now totally dependent on ANT to perform - all the steps involved in creating a release, including - compilation, jar file creation, generation of the javadocs, and for - the creation of the distribution tar and zip files. [*] - - - Removed org/apache/log4j/varia/ResilientFileAppender.java which was - bogus to begin with. [*] - - - XMLLayout will now mark some output as <![CDATA[ .. ]]> so that it - does not get interpreted by the XML parser. This was suggested by - Mathias Bogaert like a long list of other fixes. [*] - - - Corrected a bug in CyclicBuffer.resize method that would not update the - next insertion point. Thanks to Ole Bulbuk for accurately reporting - the bug. [*] - - - The LoggingEvent class now supports serialization of priorities - derived from the org.apache.log4j.Priority class. [*] - - - Improved the search method for finding the "log4j.properties" file in - the static initializer of Category class. Thanks to Calvin Chan for - supplying a better method. [*] - - - The code handling the FCQN (formerly instanceFQN) parameter was - cleaned up. There is now a well-established and simple manner for - sub-classes of Category (or wrapper classes) to define the FCQN - variable: just define a static variable, say FCQN, consisting of - the fully qualified class name of the subclass or wrapper, supply - this variable as an argument to forcedLog method if and when - the sub-class or wrapper invokes that method. [*] - - - Made the instanceFCQN an instance variable instead of a class - static in Category.java. In related move, the Category constructor - now takes an additional argument setting the instanceFCQN. This - makes life less miserable for Category subclasses. [*] - - - Corrected a bug in the OptionConverter.instantiateByClassName - method that would not return the defaultValue in case of error. Thanks - to Matthieu Verbert for identifying this bug. - - - Corrected the missing stack trace in e-mails generated by the - SMTPAppender when using certain Layouts. [*] - - - Updated the "Adding Conversion Characters to PatternLayout" - document to reflect the latest changes to the code. Also added the - org/apache/log4j/examples/appserver directory containing the - associated example code. [*] - - - Added the BufferSize option to the AsyncAppender. [*] - - - Eliminated the SecurityExceptions thrown in Applets. Thanks Timur - Zambalayev for reporting this bug. [*] - - - Fixed the erroneously thrown IOInterruptedException when the AsyncAppender - was closed. Thanks to Tom Palmer for accurately reporting this bug. [*] - - January 12th, 2001 - - - Release of version 1.0.4 (the 20th major release) - - - Corrected a serious bug in Hierarchy.java that would cause a - NullPointerException depending on the order of instantiation of - categories. Thanks to Wolfram Gewohn for reporting this bug. [*] - - - Corrected a bug in the getOptionsStrings method of SMTPAppender - that omitted to mention the EvaluatorClass option. Thanks to Mark - Balster for reporting this bug. [*] - - January 11th, 2001 - - - Release of version 1.0.3 (the 20th major release) - - - Fixed a NullPointerException occurring in AsyncAppender after - invoking Category.shutdown. Thanks to Frank-Olaf Lohmann for - reporting this bug. [*] - - - Modified the OptionConverter.selectAndConfigure method to take an - extra argument of type Hierarchy. This method is used internally - and should not affect most users. [*/**] - - - Added the warn method to LogLog which is used internally by log4j - to report on itself. [*] - - - Displaced a number of HTML files under the docs directory. The new - structure is compatible with the jakarta site and results in a - more consistent navigation experience. [*] - - - Made a few improvements in the javadocs. [*] - - January 11th, 2001 - - - Release of version 1.0.2 (the 20th major release) - - - Added the missing build.inc file to the distribution. No code - changed. - - January 10th, 2001 - - - Release of version 1.0.1 (the 20th major release) - - - This version corrects some documentation and build script bugs; - code has not changed. - - January 8th, 2001 - - - Release of version 1.0 (the 20th major release) - - - Package hierarchy now starts at org.apache.log4j. [***] - - The following perl command can help in the transition: - - > perl -p -i.bak -e "s/org.log4j/org.apache.log4j/;" file1.java .. fileN.java - - - Added the fatal() family of methods to the Category - class. Moreover, the EMERG priority has been removed from the - Priority class. This priority has been replaced by the FATAL - priority that is more widely accepted. This change will - require EMERG log statements to be replaced by FATAL log - statements. Assuming EMERG log statements are rare, this should - have a small but bearable impact on existing client code. - - Moreover, the Unix Syslog priorities ALERT, CRIT and NOTICE are no - longer recognized. Support for these priorities was minimal and - few users should suffer from these changes. [**] - - - Removed the methods setRootPriority, getRootPriority as these - methods were redundant and had been previously deprecated. [**] - - - Removed the DOM Level 2 dependency in DOMConfigurator. This makes - log4j XML configurable using Sun's parser or Apache's Xerces. [*] - - - The static initializer of the Category class now takes the - log4j.configuration system property to search for its configuration - file. The type of the configurator used to parse the configuration - file depends on the value of the log4j.configuration system - property. [*] - - - Enhanced the PropertyConfigurator and DOMConfigurator to support - customisation of independent Hierarchy instances. The - org.apache.log4j.net.SocketServer has been enhanced to take - advantage of this functionality. The old code of SocketServer has - been moved to SimpleSocketServer. [**] - - - Enhanced the PropertyConfigurator to support variable substitution - for all options *values* (but not keys!). [*] - - - Categories are now aware of the Hierarchy they are linked to. This - will provide a basis for several performance enhancements planned - for the future. [*] - - - Added support for object rendering. It is now possible to register - an object renderer for a given object type. When the given object - needs to be logged log4j will invoke the corresponding renderer to - transform the object into a String. - - As a result of this enhancement, all the String forms of all the - printing methods such as debug(String), info(String) have been - removed as they are no longer necessary. This change should be - backward compatible but requires recompilation of old client - code. Thanks to Michael Smith for noting the recompilation - requirement. [**] - - - Added support for user defined category factories in the - PropertyConfigurator. Thus, it is now possible to configure log4j - with a properties file and still use custom Category - sub-classes. The DOMConfigurator had already a finer grain - support. [*] - - - Added the SMTPAppender that in case of an error or fatal event - sends an e-mail containing latest N logging events in its buffer, - where N is chosen by the user. [*] - - - Added the method getInstance(Class) to the Category class. [*] - - - Corrected a bug in configureAndWatch method of configurators that - would configure log4j only after an unnecessary delay. [*] - - November 30, 2000 - - - Release of version 0.9.1 (the 19th public release) - - - Corrected a typo making NTEventLogAppender.dll register the wrong - category message file. Thanks to Peter Hayes for accurately - reporting this bug. [*] - - - The DOMConfigurator and PropertyConfigurator can now automatically - detect modified configuration files and re-read them. [*] - - - Added AsyncAppender which buffers log requests and serves them - at a later time. AsyncAppender can increase logging performance - tremendously if logging operations are interspersed with long - and blocking non CPU-intensive operations, typically I/O or network - access. For CPU intensive applications, using the AsyncAppender - will actualy degrade logging performance by 10 to 25 percent. [*] - - - The log4j.dtd has been modified to allow appenders to refer to - other appenders by IDREF. [*] - - - The DOMConfigurator has been modified to take advantage of ID/IDREF - attributes when referring to appenders. This change requires a - DOM Level-2 API compliant parser. DOM Level-2 java bindings are - available at - http://www.w3.org/TR/1999/WD-DOM-Level-2-19990923/java-binding.html. - - - Added the configure(String filename) method to DOMConfigurator. - This method requires the presence of a JAXP compatible parser. - - At this time, the only DOM2 and JAXP compatible parser seems to be - the Apache xerces parser. - - - Added the PriorityMatchFilter allowing filtering by exact priority - match. This was a common request by users. [*] - - - The configuration of a category is now an atomic operation. This - ensures that log requests are not lost while configuration is in - progress. Anders Kristensen was to first to observe the potential - problems in non-atomic configurations. [*] - - November 20th, 2000 - - - Release of version 0.9.0 (the 18th public release) - - - The "log4j" element has been renamed to "configuration" in the - log4j DTD. This change requires that log4j configuration files - written in XML be modified. Since the log4j element figures only - once in the XML file, this change should take little time. [**] - - - ResourceBundles are now category instance specific and no longer - class static. Moreover, like other properties resource bundles - are inherited from the category hierarchy. [**] - - - The jar files log4j.jar and log4j-full.jar now contain versioning - information in their respective manifest files. [*] - - - Corrected an inconsistency in the NTEventLogAppender which broke it. - - - Fixed a bug where configuration files were not parsed correctely - due to trailing spaces in option values as returned by - java.util.Properties. Trailing spaces are now removed from option - values. This bug was quite disconcerting because the - trailing spaces cannot be seen without careful examination of the - configuration file. [*] - - - Added the XMLLayout. - - The output of the XMLLayout consists of a series of log4j:event - elements. It does not output a complete XML file. The output is designed to - be included as an external entity to form a well-formed XML file. [*] - - - Added a new abstract class org.log4j.helpers.DateLayout. The TTCCLayout - now extends DateLayout. [*] - - - Corrected a rather subtle performance bug in the buffer management code - in PatternLayout. Thanks to Vladislav Dutov and Constantine - A. Plotnikov for for insisting on the correction of this bug. [*] - - - Created a new package called org.log4j.spi. This new package - holds classes that are hidden from the casual user but are needed - to extend log4j. [*] - - - Added org.log4j.varia.ExternallyRolledFileAppender to handle - externally triggered file rollovers. [*] - - - Added support for multiple hierarchy trees. [*] - - - PatternLayout can now be subclassed to support new conversion - patterns. [*] - - - Extended the DOMConfigurator and the log4j DTD to properly handle - sub-classing of Category and Priority classes. - - There have been also minor adjustments to other classes to handle - sub-classing. These changes should be invisible to users. - - All categories except the root category can be sub-classed and also - assigned priorities sub-classing org.log4j.Priority. - - The root category always exists and CANNOT be subclassed. - - The ProppertyConfigurator remains unchanged. Thus, it does not - handle extensions of the Category class. [*] - - - Added filter support in appenders. The DOMConfigurator and the - log4j.dtd have been enhanced to support filters. [*] - - - Added error handling support to appenders. The DOMConfigurator and the - log4j.dtd have been enhanced to support filters. [*] - - - Added support for correct interpretation of location information in - IBM's Visual Age environment. Thanks to Wolf Siberski for supplying - the relevant patch. [*] - - - Added getAdditivity method to Category. This feature was requested - by Constantin Mitran. (mitran at ecircle.de) [*] - - August 27, 2000 - - - Release of version 0.8.5b. - - - Corrected multiple bugs in default initialization code of - Category class. Thanks to Jeff Turner for identifying and supplying - corrective patches. [*] - - August 24, 2000 - - - Release of version 0.8.5a. - - - Added the %n conversion character to PatternLayout so that a line - separator can be specified in a platform independent way. [*] - - - In 0.8.5 internal Priority integer values were decoupled from the - Unix Syslog values. This broke SyslogAppedder. A new function - Priority.toSyslogInt is introduced to solve this bug. [*] - -Corrected a bug where the internal prtar tzvf iority integer - - August 23, 2000 - - - Release of version 0.8.5. - - - All log4j internal output is now prepended with the string - "log4j: ". This makes is easier to differentiate log4j internal - logs from messages output by other sources. [*] - - - Sub-classes of Category class must now specify their fully - qualified name when constructing logging events. This allows the %C - conversion specifier in PatternLayout to work properly even with - sub-classes or wrappers of Category. [*] - - - Added the method disableDebug to BasicConfigurator. This method - disables all print requests of debug priority regardless its - category. Similar methods disableInfo, disable, disableAll and - enableAll have also been added. Disable type methods can be - overriden by setting the log4j.disableOverride system property. - - Calling BasicConfigurator.disableInfo is equivalent to the now - deprecated flagAsShippedCode method. [*] - - - Given the above changes, the system property - log4j.shippedCodeFlagOverride is no longer honored. [**] - - - It is now possible to sub-class Category. The sub-classes may - continue to adhere to the category hierarchy. This was a frequently - requested feature. [*] - - - Corrected a problem with the additivity flag being ignored in - categories without appenders. This bug was discovered by Anders - Kristensen. [*] - - - Added a method BasicConfigurator.resetConfiguration to reset the - log4j environment. This method should be used sparingly. [*] - - - At the initialization of the Category class, the file - log4j.properties will now be searched from the search path used to - load classes. If the file can be found, then it is fed to the - PropertyConfigurator.configure(java.net.URL) method. [*] - - - Failing to access system properties within the static initializer - of BasicConfigurator class is no longer reported as an error but as - a debug message. Thanks to Gilles Schlienger for reporting this - problem with applets. [*] - - - Corrected a bug which caused infinite loops when using conversion - patterns with a single element, fortunately under very rare - circumstances. This bug was first reported by Igor Potraev, the - author of log4p. It was independently reported by Joe Haberl from - IBM Global Services. [*] - - - Added a mechanism to lazily remove references to dead threads in - the NDC class. Indeed, in previous versions calling NDC.pop within - a thread but forgetting to call to NDC.remove before exiting (that - thread) resulted in a memory leak. [*] - - - Corrected a huge memory leak in SocketAppender. This leak was due - to the ObjectOutputStream indefinitely holding a reference for each - written to the stream. Thanks to Dan MacDonald for very accurately - describing this bug. [*] - - - The log and l7dlog methods in Category no longer ignore the shipped - code flag. This bug was reported by Mario Schomburg. [*] - - - Added missing NDC information to LoggingEvent.writeObject - method. [*] - - - Corrected handling of SocketException in SocketNode. Thanks to - Gerald Gutierez (ggutierez@emobiledata.com) for reporting this and - the previous problem. [*] - - - Phased out custom shell scripts to build java documentation and jar - files in favor of Jakarta's ANT. It was becoming a nuisance to keep - the ANT build file in sync with the custom shell scripts. [*] - - - May 11, 2000 - - - Release of version 0.8.4d. - - - The NT EventViewer no longer complains about missing message 4096. - - - Minor corrections in documentation. - - - Added missing icons GIFs into the distribution. - - - SocketNode now attempts to close the socket when exiting. Thanks to - Moses Hohman (mmhohman@rainbow.uchicago.edu) for noting this. - - - Removed the com.ibm.log4j from the javadoc directory. This seems to - confuse VAJ. Thanks to Steve Ashcroft for reporting this problem. - - May 5, 2000 - - - Release of version 0.8.4c. - - - As a result of the infinite loop problem (see next item), added - over 800 new test cases to stress-test the code in CategoryFactory - class where category creation occurs. [*] - - - Under certain rare circumstances the Category.getInstance method - entered an infinite loop. Thanks to Mario Schomburg from IBM Global - Services / Hannover for identifying this problem and proposing a - patch. [*] - - - DOMConfigurator and the log4j.dtd were out of sync on the type of - the priority directive. As a result, priority directives all - defaulted to DEBUG. Thanks to Peter (petervt@users.sourceforge.net) - for accurately reporting this bug. [*] - - - Minor additions to the FAQ. [*] - - - Added the NumberCruncher example showing how the NDC class can be - used to distinguish output from different clients. [*] - - - Added the %x conversion specifier to the TTCC_CONVERSION_PATTERN in - the PatternLayout class. This is consistent expected output of - Trivial.java example. Thanks to Jerome (schrom@users.sourceforge.net) - for reporting this bug. [*] - - May 3, 2000 - - - Release of version 0.8.4b. - - - The value of the additivity option would not be parsed properly by - the ProperytConfigurator if the line containing the option - contained trailing spaces. [*] - - - Release of version 0.8.4a. - - - The localized logging methods (l7dlog) omitted priority based - evaluation and erroneously logged all requests. [*] - - May 1, 2000 - - - Release of version 0.8.4. - - - The close method was added to the Appender interface allowing - appender implementations to release any resources they may have - allocated. [*] - - - The package naming scheme of changed from "com.ibm.log4j.*" to - "org.log4j.*". The new naming reflects the open source nature of - the project and is consistent with the URL http://www.log4j.org. [***] - - - Added internationalization support. See the newly introduced l7dlog - methods in Category class. [*] - - - In the FileAppender, the File option now admits variable - substitution. For example, if "java.home" system property is set - to /home/xyz and the File option is given the value - "%{java.home}/test.log", then File option will be interpreted as - "/home/xyz/test.log". - - Thanks to Avy Sharell (sharell@online.fr) for contributing this - feature. [*] - - - SocketAppender is now officially part of the package. It is capable - of sending logging events to a remote SocketNode. The SocketNode - logs events according to server (local) policy. For example, a - client can log events to a local file and also send them to a - remote server (a SocketNode). This server can log the event to any - number of files, to the console, to any number of TextPaneAppenders - and even re-transmit the event to another server, and so forth. - - This paradigm is common in most logging systems, e.g. Syslog and NT - Event Log. Many thanks to Andrew Harrison for showing a way to - actually implement the paradigm. [*] - - - The Category.callAppenders method now accepts a LoggingEvent - instead of creating one itself. This was necessary to accommodate - events generated at a remote client. [*] - - - LoggingEvent class changed slightly to support remote logging. The - category field (a Category) has been replaced by the categoryName - field (a String). [*] - - April 14, 2000 - - Release of version 0.8.3b - - - Corrected a bug in Category.removeAppender(String) which would - never remove the desired appender. Thanks to Moses Hohman for - reporting this bug. - - Release of version 0.8.3a - - - Corrected a bug RollingFileAppender which would throw an uncaught - exception in case output file could not be opened for - writing. Thanks to Vinay Aggarwal for signaling this problem. - - April 13, 2000 - - - Release of version 0.8.3. - - - The log4j.override key defined in BasicConfigurator has been - renamed to log4j.shippedCodeFlagOverride. [**] - - - The getCurrentCategories method in the Category class would not - return the correct value. Thanks to Timothy Potter - (tpotter@agency.com) for reporting this problem. [*] - - - Appenders now admit a priority threshold as an option. All requests - with a priority lower than the appender's threshold priority are - ignored by the appender. [*] - - - Integrated Christopher Taylor's DOMConfigurator parsing XML - configuration files. [*] - - - The jar file log4j-net.jar has been replaced by log4j-full.jar. It - contains DOMConfigurator.class in addition to the com.ibm.log4j.net - package. [**] - - - Added support for the ANT build tool. Thanks to Christopher Taylor - for supplying the build.xml file. ANT is available form - http://ant.apache.org. [*] - - - FileAppender's File option now accepts the values "System.out" or - "System.err". If one these values is suppiled in a configuration - file then the output is directed to the corresponding stream. - Moreover, the default constructor of FileAppender no longer sets - System.out as an output target nor does it define a default - layout. [*] - - - Added caller class (C), caller file name (F), caller line number - (L), caller method name (M) conversion specifiers to the - PatternLayout class. - - The category conversion specifier now takes an optional precision - modifier allowing the user to control the number of right most - components in the category name that will be printed. - - Corrected a bug occuring when the caller file name and line number - information were unavilable due to JIT compilation. In that case, - the PatternLayout would not properly use the rest of the available - location information. [*] - - The above enhancements and bug-fixes originate from comments by - Nelson Minar (nelson@monkey.org). - - March 23, 2000 - - - Release of version 0.8.2. - - - The SimpleLayout and TTCCLayout are replaced by the PatternLayout - in the log4j.jar file to keep its size small. These two layouts are - still part of the package. - - - The PatternLayout class is introduced. This new layout is - configurable using a conversion pattern which is parsed at - runtime. This allows the user to choose the output layout without - writing any code and only at a marginal performance cost compared - to the dedicated layouts such as SimpleLayout and TTCCLayout. The - PatternLayout also allows the user to determine minimum and maximum - field lengths. - - The PatternLayout was written by Jim Cakalic - (jim_cakalic@na.biomerieux.com). [*] - - - All internal components now use LoggingEvent instances to specifiy - logging information. - - - Corrected a problem with a missing variable initialization in - SyslogAppender. This caused NullPinterException to be thrown when - logging exceptions. - - Added a default constructor to SyslogAppender. The lack of this - constructor caused PropertyConfigurator to throw a - java.lang.InstantiationException when the appender type was set to - be SyslogAppender. - - Thanks to Yves Bossel (ybossel@opengets.cl) for accurately - identifying these bugs. - - Modified some other related option handling code in - SyslogAppender. [*] - - - Made NDC.get public access instead of default access. Thanks to - Y. J. Chun (monac@softonnet.com) for reporting this problem. [*] - - - PropertyConfigurator now parses the additivity option for - categories. [*] - - - Corrected the value of the ADDITIVITY_PREFIX constant to match the - documented value, that is "log4j.additivity". [**] - - - Corrected a really bad bug where System.out would be closed when - PropertyConfigurator.configure was called. Thanks to Christopher - Taylor (cstaylor@pacbell.net) for tracking and reporting this bug. [*] - - - The PropertyConfiguator now prints debug messages if the flag - "log4j.configDebug" is defined in the configuration - file. Previously, only if the system property "log4j.configDebug" - was set would debug messages be printed. A question by Shawn - Kircher (skircher@vninet.com) induced this change. [*] - - - In AbsoluteTimeDateFormat, DateTimeDateFormat and ISO8601DateFormat - the separator between the seconds and milliseconds has been changed - to comma from full stop, in order to be compliant with ISO8601's - preferred sign. Thanks to Jim Cakalic - (jim_cakalic@na.biomerieux.com) for pointing out this discrepancy - with the standard. [*] - - - Corrected a bug where RollingFileAppender would not work - properly on Windows systems. Thanks to Heinz Richter - (heinz.richter@ecmwf.int) for noting this problem. - - February 19, 2000 - - - Release of version 0.8.1. - - - Core classes are now independent of the format of the options - file. Configurable core classes implement the OptionHandler - interface. OptionHandlers allows configurators to learn the - relevant option names. The configurator feeds option values to the - OptionHandler which configures itself. - - As a result of these changes, the Init class has been broken down - to two separate classes: the BasicConfigurator and the - PropertiesConfigurator. [**] - - An XML configurator for 0.8.0 has been already written by - Christopher Taylor (cstaylor@pacbell.net). - - - Added multiple appender support per category. The appenders follow - the category hierarchy, i.e. a child category inherits the - appenders of its parents. - - - Added an assert() method to the Category class. Steven Marcus - (srnm@awaretechnologies.com) requested this addition. [*] - - - Atomatic stack printing is no longer supported. This was an unused - and unreliable feature which unnecessarily complicated the - code. [*] - - - log4j now emits a single warning message when no appender to write to - could be found. This is typically the case when the user forgets - to configure the log4j environment. This change was suggested by - Jim Cakalic (jim_cakalic@na.biomerieux.com). [*] - - - RollingFileAppender adds file roll over capability--implemented by - Heinz Richter (heinz.richter@ecmwf.int). [*] - - - Corrected a bug where a java.lang.NoClassDefFoundError would be - thrown because com.ibm.log4j.helpers.SyslogTracerPrintWriter was - not included in log4j.jar. Thanks to Jim Cakalic (jim_cakalic@na.biomerieux.com) - for signaling this bug. [*] - - February 9, 2000 - - - Release of version 0.8.0. - - - There has been an important API changes. The Log, NOPLog and ILog - classes have been removed. Their functionality has been migrated to - the Category class. [***] - - In this release, instead of writing - - ILog.debug(CAT, "Some message."); - - one will write - - CAT.debug("Some message."); - - Arndt Schoenewald <arndt@ibm23093i821.mc.schoenewald.de> observed that - one could use the Category objects directly for logging. - - - It is no longer possible to instantiate Category objects directly. - Instead, one would use the factory method - Category.getInstance(String name). [***] - - There category instantiation code was moved to CateogryFactory - class. This class has package visibility and remains hidden from - the user. - - This stylistic improvement was suggested by Luke Blanshard - (luke@quiq.com). - - - The Init class offers methods to initialize the log4j - environment. The Init.flagAsShippedCode method replaces the NOPLog - class. - - - Changes in the documentation to reflect the API changes. - - - The NDC.cloneStack and inherit methods now tolerate null-stacks. [*] - - - January 29, 2000 - - - Release of version 0.7.5. - - - TTCCLayout now takes a java.text.DateFormat object as a - parameter. The task of formatting the date is delegated to this - object. - - Added four classes extending the java.text.DateFormat class. These - are RelativeTimeDateFormat, AbsoluteTimeDateFormat, - DateTimeDateFormat and ISO8601DateFormat classes. - - Thanks to Arndt Schoenewald <arndt@ibm23093i821.mc.schoenewald.de> - for suggesting the ISO8601 date format. - - These four classes can be parametrized with a particular - TimeZone. The TTCCLayout class now accepts a new configuration file - option called "TimeZone". - - These four DateFormats are less malleable than the - java.text.SimpleDateFormat but they are also much faster. - - As a consequence of these changes, the setRelativeTime, - setDatePrinting methods in TTCCLayout have been removed along with - the associated configuration file options RelativeTime, - DatePrinting and TimePrinting. [**] - - The current code is inspired by code contributed by - Heinz Richter (heinz.richter@ecmwf.int). - - - The Log.emerg method has been deprecated. If you use statements of - EMERG priority, please use the Log.log form instead. [**] - - - Added getDepth and setMaxdepth methods to the NDC class. This makes - it easier to manage the nested context depth especially when - callees push but forget to pop. - - - Moved the documentation in com/ibm/log4j/package.html to - com/ibm/log4j/overview.html. Many users were failing to read the - com/ibm/log4j/package.html description due to the unfortunate - layout of the text. Hopefully more people will read the package - overview in its present location. - - - Added the com.ibm.log4j.net package for doing remote logging using - TCP sockets. This is still experimental code. - - - Added new debug, .., emerg methods that do not require a category - parameter. They assume the "root" category, that is the decision to - whether print or not is made by comparing the statement's priority - with the default priority. [*] - -January 21, 2000 - - - Release of version 0.7.4. - - - Added a new ILog.init method accepting an Appender and a - configuration file as parameters. - - - FileAppender's setWriter and setFile methods where not instantiating - a new tracer. This caused stack traces to be lost! SyslogAppender - had a similar problem. [*] - - - The FileAppender and SyslogAppender where not calling the layout's - readConfig method to set layout specific options. Thanks to Heinz - Richter (heinz.richter@ecmwf.int) for reporting this bug. [*] - - - Corrected a bug in Log.log() method where the appender was always - called with Priority.DEBUG. Thanks to Oliver Boehm - (Oliver.Boehm@abaxx.de) for reporting this bug. [*] - -January 14, 2000 - - - Release of version 0.7.3. - - - Added Syslog compatibility. One can now choose (at runtime) between - remote syslog logging or file logging. [*] - - Syslog logging performance, although not appalling, is significantly - slower than file logging. - - - Priority class was enriched with the previously missing priorities - NOTICE, ALERT and CRIT. The internal constants were also aligned with - the syslog counterparts. [*] - - - Added the Log.log method to support the new priorities. [*] - - - TracerPrintWriter is now an independent class instead of being a - nested top-level class in Tracer. [*] - - - A number of writers, namely the SyslogWriter, SyslogQuietWriter, - SyslogTracerPrintWriter, were added to the helper package. [*] - - - Log.force method was removed. The various Appender.doAppend - implementations take over its functionality. [*] - - - FileAppender and SyslogAppender now use QuietWriter. QuietWriter is - a FilterWriter which hides exceptions and instead emits a single - warning message to System.err. [*] - - - The layout is now an initialization parameter to the appender - type. Previously, the layout and the appender where independent - parameters to the Log constructor. [**] - - - Many small improvements and corrections in the documentation. - Syslog related documentation remains sparse. - - - ILog.init() and ILog.init(String configFile) have been changed to - call ILog.init(,,,) with "com.ibm.log4j.Log.class" as the first - parameter. This makes it easier for people to get familiar with log4j. [**] - - - Added missing files to the make directory. These files are useful - for those wishing to use the log4j make environment. Thanks to "Lee - Hall" <LHall@JavaFoundry.com> for reporting this omission. [*] - - Until recently the make environment failed to compile RMI stubs in - a single run. This nagging problem has been corrected thanks to - help from Thomas Eirich (IBM Zurich Research Lab). - -January 4, 2000 - - - Release of version 0.7.2. - - - Some users have been rightly complaining about the verbosity - TTCCLayout's date output. The full date output is now shortened to - "dd MMM YYYY HH:mm:ss.SSS" for example, "06 Nov 1994 08:49:37.459" - In addition, users may now choose to print only time information, - as in "08:49:37.459". [*] - - - The package now uses Writer instead of OutputStream as its output - target. This makes the log4j code smaller and easier to - understand at the cost of a slight performance degradation. As a - result of this change a few method names in FileAppender class were - changed. [**] - - - Preliminary experiments with SyslogAppedner and SyslogLayout show - that syslog compatibility is not far away. The difficultly is - adding syslog compatibility without making radical changes to the - current log4j architecture. - - - Corrected a bug in the NOPLog.createInstance method which always - created a Log singleton even if the system property "log4j.logType" - was set to NOPLog. Thanks to Robert Gottofrey - (Robert.Gottofrey@wdr.com) for reporting this bug and the - associated test case. - - - Removed the inconsistent "Layout" configuration option in - Log.readConfig(). This change should be transparent to most - users. [*/**] - -December 20, 1999 - - - Release of version 0.7.1. - - - The LogCreationManager class has been removed. Its functionality - has been transfered to the createInstance and getInstance methods - in the Log and NOPLog classes. The new way of creating instances is - both simpler and less error prone although just as flexible. [**] - - As a result of these changes, the init family of methods in the - ILog class have been adjusted to the new way of creating the log - singleton. - - - The Appender interface has been introduced. The method of writing a - log statement into an output stream can now be varied by using a - different Appender. The new FileAppender offers the same - functionality that was previously part of the Log class. [**] - - - Changed the time format used in TTCCLayout to be of the form "Day, - dd MMM YYYY HH:mm:ss.SSS GMT" for example, "Sun, 06 Nov 1994 - 22:49:37.459 GMT". This format is almost the same as the format - specified in RFC 1123 and also the format recommended in RFC - 2616. The only difference is the additional milliseconds - information. [*] - - - The layout specific options were not read from the configuration - file due to a missing instruction. Many thanks to Vikram Sridharan - (Vikram.Sridharan@alysis.com) to patiently pointing out this - omission to an unbelieving maintainer. [*] - -December 16, 1999 - - - Release of version 0.7.0. - - - Version 0.7.0 and above will be distributed under the IBM Public - License (IPL). The IPL is an approved open source license (see - http://www.opensource.org/licenses/ for a list). It grants similar - rights to the previous ALPHAWORKS license agreement, in particular, - the right to redistribute and to modify the package. - - - The Log class can now be parameterized with a Layout object. - Layouts determine the format of what is printed, where as the Log - class decides when to print and to where. [**] - - As a result of this modularization, the CGULog and NOPCGULog - classes no longer exists. CGULog class has been replaced with the - TTCCLayout (Time Thread Context Category). This should make it - easier to create new log output formats. - - Some time in the near future, the Log class will be further broken - down to allow different strategies for writing to output streams. - - - Renamed com.ibm.util.log hierarchy to to com.ibm.log4j. I wanted to - do this for some time. I feel release 0.7.0 was the last - opportunity to do so. I am sorry for the the trouble caused by this - change. [**/***] - - - New NDC class. This class implements nested diagnostic contexts as - suggested by Neil Harrison in the article "Patterns for Logging - Diagnostic Messages" part of the book "Pattern Languages of Program - Design 3" edited by Martin et al. Nested diagnostic contexts is a - nifty feature that was missing up to now. [*] - - The StressNDC test class seems to break JDK 1.2.2 beta on AIX. On - Linux and NT using sun's JDK 1.2.2 it seem to work OK. In any case, - tests done with StressNDC and associated perl script seem to - indicate that the NDC class is bug-free. - - - Corrected a date formatting bug in CGULog class where on some - environments the wrong month was printed. Thanks to Christopher - Williams (Christopher_Williams@mail.northgrum.com) for signaling - this bug. Also changed the month format from a number to a three - letter abbreviation such as "Jan", "Feb", ..., "Dec". The new - format is unambiguous regardless of local date format. [*] - -December 8, 1999 - - - Release of version 0.6.2. - - - Clearer documentation with still much room for improvement. - - - Corrected a bug in the Tracer class which always used the Unix line - separator instead of the system specific separator. Thanks to - Vikram Sridharan (Vikram.Sridharan@alysis.com) for singaling this - bug. [*] - - - Corrected a runaway comment which gulped the CGULog.readConfig - method. [*] - - - Added the init family of methods to the ILog class to ease the - setup of a basic logging environment. Thanks to Mark Donszelmann - (Mark.Donszelmann@cern.ch) for this enhancement. [*] - - - Just an hour after releasing version 0.6.1 detected and corrected a - bug where the Tracer class would correctly print Exception stack - trace but not the type of the Exception. Replaced the - distribution on www.zurich.ibm.com without changing the version - number. I hope nobody is using the intermediary (and buggy) release - of 0.6.1. [*] - -November 16, 1999 - - - Release of log4j version 0.6.1. - - - Better documentation with still much room for improvement. - - - For consistence sake, added setDefaultPriority and - getDefaultPriority methods to the Category class and deprecated - setDefaultPriority in the Log.class. [**] - - - Corrected a major bug where if two categories were homonyms the - second instance would not be properly initialized. - - - Increased the speed of Exception logging from about 4000 - microseconds to about 1000. It seems that for some people Exception - logging is performance critical. Improved implementation is a - variant of Nocolai's (XNH@crisplant.com) implementation. [*] - -November 9, 1999 - - - Release of log4j 0.6.0 with incomplete documentation. - - - Added a stress test program to debug the new Category class. It - turns out that the test program was as hard to get right as the - Category class. Given the favorable results of the stress test I am - quite confident that the new class is now bug free. This assumption - has been proven to be wrong. See above. - - - Created a new class called Category to manipulate categories - instead of plain Strings. The new class is just as easy to use. - However, the evaluation of whether to log or not to log is at least - 10 times faster. The NOP class performance remain unaffected by the - change. (You can't improve on the performance of an empty function - call.) - - Many thanks to Alex Blewitt "Alex.Blewitt@ioshq.com" for his - valuable comments. He was the first to observe that finding Strings - in a hash table was an expensive operation. - - This change will require some recoding on your part. See the FAQ - for more details. [***] - - - Modified the force in Log and CGULog method to use a byte[] buffer - instead of a StringBuffer. The old code was clearer but the new one - is at least 25% faster. [*] - - - Added regression testing. - - - We now enforce a policy where the OutputStream set by - setOutputStream is a user managed resource whereas the OutputStream - opened using setLogFile is the Log class' responsibility. - - The setLogFile method now closes any previous OutputStream if only - if opened through setLogFile. If the previous OutputStream was - opened by the user and set through setOutputStream the previous - OutputStream is untouched. - - Similarly, setOutputStream will close any previous OutputStream if - and only if it was opened using setLogFile. - - - Added a new method logOutputStreamExists to the Log class allowing - the programmer to check if there is already an opened stream before - trying to set a new one. A stream can be opened as a byproduct of - reading the configuration file. - - - Changed the behavior of the (private) Log.Append method in case of - failure to write to the OutputStream. - - Previously, in case of failure, we reverted to System.err. Now, we - emit a warning message and discard all future log messages. The - new behavior is consistent with our current unreliable logging - semantics. The change prevents an otherwise functional program - from failing because the terminal is flooded with logging messages. - - - Renamed the iLog to ILog to remain consistent with our class naming - scheme. The initial intention was to add ILog and deprecate - iLog. However, I am running CVS on a fat16 partition, causing - serious problems when files differ only in case. - - - Corrected a bug where the LogFileName was not remembered. Thanks to - Jens for signaling this bug. - -October 28, 1999 - - - Release of log4j v0.5a - - - Now the programmer can choose to truncate the log file instead of - always appending to it. This functionality was first requested and - intially implemented by "Jens Uwe Pipka" jens.pipka@gmx.de. [*] - - - setLogFile now opens the requested file instead of having the - Append function open it later. Cleaned up some related code in the - Append function. Although nobody has requested it, there is still - no method to close the log file. This is harder to implement - reliably than it sounds. [*] - - - Simplified setLogOutputStream so that it does no longer return the - previously set OutputStream. [*] - -October 27, 1999 - - - Released log4j v0.5 - - - Joe Walker (joe@eireneh.com) observed that the - LogCreationManager.getSingleton mechanism was cumbersome. There is - now a new class iLog (indirect Log) which hides the need to call - getSingleton. Performance testing on my 233Mhz Thinkpad shows that - this indirection has small performance impact on non-logged calls - in the order of 40 nanoseconds. The impact on logged calls is - negligible. [*] - - - Added a jar file to the distribution. The jar file contains only - the files you would need to use log but not other classes needed - for testing nor examples. - - - Corrected a bug where CGUNOPLog was not integrated to the Makefile. - - - Added new public methods isDebugEnabled and isInfoEnabled to allow - programmers to check whether a debug/info statement will be logged - without incurring the cost of message parameter construction. This - addition was suggested by Luke Blanshard Luke@quiq.com. [*] - - - Renamed the private method evaluate to isEnabled. Also made it - final with no apparent speed gains. In addition, made the - Log.force method public. [*] - - - New syntactic sugar debug, ..., emerg, methods to log objects. [*] - - - Modified the interface to deal with Throwables and not just - Exceptions. My thanks to Luke Blanshard for signaling this "bug". [*] - - - Added more tests to the LogPerformance class. In particular, to - test the influence of indirect debug calls. - - - Added a "make" mini-tutorial for those who want to modify the code. - - - License updated to standard alphaWorks license allowing - modifications to source code. However, this license explicitly - requires that modifications be communicated back to alphaWorks. - -October 15, 1999 - - - Initial availability on alphaWorks. - -Refer to the FAQ for the lineage of the package. - - diff --git a/docs/TROUBLESHOOT.html b/docs/TROUBLESHOOT.html deleted file mode 100644 index 82590c2a60..0000000000 --- a/docs/TROUBLESHOOT.html +++ /dev/null @@ -1,301 +0,0 @@ -<html> -<head> -<title>Troubleshooting log4j - - - -

Log4j troubleshooting

- -

Ceki Gülcü Paul Glezen -
February 2002 -

- -
- -

Here is a list of commonly encountered problems when using log4j:

- - - -
- -

log4j tells me to initialize properly.

- - Logging output is written to a target by using an appender. If no - appenders are attached to a category nor to any of its ancestors, you - will get the following message when trying to log: -

- -
-log4j: No appenders could be found for category (some.category.name).
-log4j: Please initialize the log4j system properly.
-
- -

Log4j does not have a default logging target. - It is the user's responsibility to ensure that all - categories can inherit an appender. This can be easily - achieved by attaching an appender to the root category.

- - -

Duplicates in log4j output.

- -

The reason for observing duplicates in log4j output is - either due to having added the same appender multiple times - to the same category (typically root) or having added the - same appender to different categories ignoring the fact that - appenders are inherited cumulatively.

- -

log4j does not eliminate appender duplicates. In other - words, if you add the same appender to a category n - times, that appender will be invoked n times to - append to its target.

- -

A slightly different cause is adding different appenders - all sharing the same underlying output target to some - category. In the most common occurrence of this phenomenon, - the BasicConfigurator.configure() method is invoked multiple - times. Each time it is invoked, this method adds an appender - with a System.out target to the root - category.

- -

One other common mistake is to forget that appenders are - inherited cumulatively from the hierarchy. For example, if - you add an appender, say A, to the root - category, all other categories will inherit A - as an appender. Thus, if you add A to a - category, say C, then an enabled statement of - category C, will print to A twice, - once because A is in root and once because it - is in C.

- -

Options are not parsed correctly.

- -

The PropertyConfigurator relies on - java.util.Properties class to read in the - configuration file. This class preserves spaces in - options. For example,

- -
-fruit=orange  
-
-is returned as an option having the key "fruit" and the - value "orange ".

- -

The spaces in the value, i.e. "orange ", are due to - invisible spaces at the end of the example shown above. Thus, some of - the options might not be interpreted correctly due to trailing - spaces.

- -

Caller location information is printed as a "?" - character.

- - Location information is extracted automatically by the PatternLayout - conversion patterns %C, %F, %M and %L. However, some just-in-time - (JIT) compilers make it impossible to extract location information. It - is also possible that the compiler that generated the byte code may - have omitted the LineNumber table as is done by -O option of javac - and jikes.

- -

You can remedy this problem by disabling the JIT compiler and by - compiling the code without the -O option.

- -

In wrappers or subclasses of Category - -

Wrappers or subclasses of Category need supply their - fully qualified class name to the Category.log method or -to Category.forcedLog methods so that the caller location -information can be extracted correctly.

- -

This approach will work correctly in all cases except if - the class invoking the extended category instance has the - same prefix as the extended category class. For example, - calling an instance of com.foo.BarCategory - from the com.foo.BarCategoryTest class will - not yield the correct caller information. To circumvent - this "bug", either perform the tests from a class with a - different name or add a dot to the fully qualified name of - the extending class that you supply to - Category.log to - Category.forcedLog methods. For the - com.foo.BarCategory example, supply the - string "com.foo.BarCategory.".

- - -

ClassCastException when -instantiating a Category subclasses.

- -

This exception is thrown because log4j does not support -homonyms. For example, the following will systematically throw a -ClassCastException

- -
-  Category c1 = Category.getInstance("bad");
-  MyCategory c2 = (MyCategory) MyCategory.getInstance("bad");
-
- -where MyCategory is a subclass of -Category. The problem occurs because the second -getInstance invocation will retrieve the category created -in the fist invocation. This instance is a Category -object and cannot be cast to MyCategory.

- -

By default, the PropertyConfigurator will - create and configure - org.apache.log4j.Category objects. Thus, if - you try to instantiate a category subclass for an already - existing category, and try to cast it to the subclass - type, you will systematically get a - ClassCastException.

- -

To address this problem, the - PropertyConfigurator admits the - log4j.categoryFactory key. The value of this - key will be used as the factory to invoke when - instantiating Category objects. - -

The DOMConfigurator has a finer grain - method for setting the class of the category object to instantiate. - - - - -

Log4j class not found/defined

- -

Naturally you should check the classpath. But you should also -be aware of the presence of multiple classloaders in the JVM: -

    -
  1. the bootstrap classloader -
  2. the extension classloader -
  3. the application classloader -
-

If you place log4j.jar in the jre/lib/ext directory -but place user-defined extensions to log4j in the application -classloader classpath, log4j configurators will not find them. - -

Servlet, JSP and EJB containers inside of application servers -usually have their own special classloaders in addition to the -three mentioned above. While this provides for a greater -degree of separation for different webapps, EJB containers and the -application server runtime itself, it can provide headaches to the -uninitiated. - -

Classloaders are usually hierarchically related. The bootstrap -loader forms the root with the extension loader as its child. The -application loader is the child of the extension loader and it's -this "app loader" that we use by default when we write standalone -Java programs. - -

Upon receiving a class load request, the classloader usually -delegates it to the parent before attempting to service the request. -This allows the bootstrap and extension loaders to deliver any classes -that are part of the JDK or its extensions. Only after this delegation -fails will the classloader attempt to find the class itself. Note that -classloaders do not delegate requests to children. - -

Application servers often use the application loader for its runtime -classes and create separate classloaders for its webapp and EJB -containers. These additional classloaders may descend directly -from the app server's runtime classloader. If log4j is placed in the -classpath of a webapp classloader, another webapp classloader will not -necessarily see it. EJBs wouldn't see it either. If log4j is intended -to be made available to all objects participating in the app server, it -should be included in the classpath of a classloader high enough in the -classloader hierarchy to be seen by all classloaders. - -

A good article on classloaders with examples using IBM's WebSphere -application server can be found -here -in PDF format. - -

I cannot log to syslogd under linux.

- -If you are trying to log to the Unix syslog under Linux using the SyslogAppender, -then the Linux syslog daemon must be configured to accept log input -from the network. Otherwise, you will get an IOException: -connection refused. - -

This can be done by adding the -r option when starting -the daemon. Or more precisely: - -

    -
  1. Login as the root user -
  2. Edit file /etc/rc/init.d/syslog -
    -case "$1" in
    -  start)
    -        echo -n "Starting system logger: "
    -        daemon syslogd -r
    -
    - -
  3. /etc/rc/init.d/syslog restart - -
- -

log4j:WARN No such property [xyz] in some.appender.or.layout

- -

If during log4j configuration you get a warning about an inexistent -property, then you have probably misspelled a property or entered a -truly unrecognized property for the component you are trying to -configure in the configuration file. - -

Log4j version 1.0 did not complain about unrecognized properties -whereas log4j version 1.1 and later do complain. - - - - - - diff --git a/docs/chainsaw-1.jpg b/docs/chainsaw-1.jpg deleted file mode 100644 index 1202ec6414..0000000000 Binary files a/docs/chainsaw-1.jpg and /dev/null differ diff --git a/docs/chainsaw.html b/docs/chainsaw.html deleted file mode 100644 index 1f50404ab7..0000000000 --- a/docs/chainsaw.html +++ /dev/null @@ -1,228 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - Log4j project - Chainsaw v2 Documentation - - - - - - - - - - - -

-
- -

Chainsaw v2 - Introduction/Table of Contents

-

Welcome to the home of Chainsaw v2!

-

Chainsaw v2 is a companion application to Log4j written by members of the Log4j development - community. Like a number of Open Source - projects, this new version was built upon inspirations, ideas and creations of others. - Chainsaw v2 has it's roots from the original Chainsaw utility written by Oliver Burn, - and with inspiration from the Log Factor 5 utility contributed by ThoughtWorks Inc.

-

Download

-

Latest Build Date: 2006-03-02 (SVN tag 'release_20060302') -

-

-

-

-

Table of Contents

- -

So what is it really?

-

 It's a GUI-based Log viewer. A picture tells a thousand words...

-

-

[zoom image]

-

These screen shots were taken on Windows 2000, running Sun JDK 1.4.2.

-

Rather than rely on a combination of tail/grep/vi or equivalent to view/query/trace-through - a huge trail of logging events, you can use Chainsaw. Chainsaw can read log files formatted in Log4j's XMLLayout, receive - events from remote locations, read events from a DB, it can even work with the JDK 1.4 logging events.

-

Quick Tour of Chainsaw features

-

  Heres just a brief run down of some of the features of Chainsaw v2:

-
    -
  • View remote events - Remote events are "received" by Chainsaw using Log4j 1.3's new Receiver concept.
  • -
  • Saved Preferences - You can fully customize each Tab the way you want it, and it will restore it's state the next time.
  • - -
  • Responsive - When events are screaming in, you don't want the GUI to meltdown. You can control - how responsive the GUI is and determine the frequency of updates.
  • -
  • Tabs/Docking - Chainsaw routes separate applications/remote hosts' events to a unique Tab within the GUI. - These tabs can be undocked from the main window. Using these features you can manage multiple application logs using the one GUI.
  • -
  • Coloring - You can specify your own rules to color each event row depending on the attributes of a LoggingEvent to - help you locate important events.
  • -
  • Dynamic and powerful filtering - Helps you locate stuff. There's support for quick-and-dirty filtering, right through to advanced expression-based filtering (e.g. "LOGGER == 'com.mycompany' && LEVEL == ERROR" ).
  • -
  • Cyclic - A tab view can support a Cyclic-based model, which constrains it's view to the last - X events, ensuring you don't hog memory. This is great for monitoring live applications.
  • -
  • Built-in documentation and tutorial - HTML-based documentation included in the package.
  • -
-

Tutorial and User Manual

-

 Chainsaw already includes help with - with a Quick Reference and a Tutorial to get you started, all viewable from within the GUI!. A User Manual will be made available around release time.

-

Distribution Notes

-

Due to Java classloading rules, it is impossible to ship the Jakarta Commons VFS extension to Chainsaw - OR have DBReceiver or JMSReceiver bundled with Chainsaw. - Several VFS filestore implementation jars cannot be shipped with Chainsaw because of licensing issues, and for JMSReceiver and DBReceiver you are required - to have proprietary driver jars locally which we obviously can't ship. You can follow these steps to enable the DB, JMS and/or VFS components inside Chainsaw. -

    -
  1. [DBReceiver] Download the DB extension to Chainsaw
  2. -
  3. [JMSReceiver] Download the JMS extension to Chainsaw
  4. - -
  5. [VFS] Download the VFS extension to Chainsaw
  6. -
  7. [VFS] Download VFS
  8. -
  9. [VFS] Download Commons Logging Jars
  10. -
  11. [VFS] Download the VFS filestore implementation jars you wish to use
  12. - -
  13. Place all these jars in your .chainsaw/plugins directory (the .chainsaw directory is in your home directory)
  14. -
  15. Start Chainsaw, which should now recognize the existence of these components and allow you to use them.
  16. -
-

-

This applies to all distributions.

-

ZeroConf - Zero Configuration

-

Chainsaw has ZeroConf elements embedded within it, but you'll need to add a few things - to your application to enable your application for ZeroConf.

-

Download:

-
    -
  1. log4j ZeroConf extension
  2. -
  3. JmDNS bundle
  4. -
  5. Add the log4j-zeroconf.jar and the jmdns.jar from these bundles and add them to your - application's classpath.
  6. -
  7. Modify your log4j configuration so that it use the ZeroConfSocketHubAppender. Here is a complete log4j.xml file that you can use as a base: -
    -<log4j:configuration debug="false" threshold="debug"  xmlns:log4j="http://jakarta.apache.org/log4j/>
    -    <appender name="zeroconf" class="org.apache.log4j.net.ZeroConfSocketHubAppender">
    -        <param name="Name" value="MyZeroConfSockeHubAppender" />
    -    </appender>
    -    <!--ROOT Logger-->
    -    <root>
    -        <level value="INFO" />
    -        <appender-ref ref="zeroconf" />
    -    </root>
    -</log4j:configuration>
    -				
    -
  8. -
- - - -
- - - - - - -
- Copyright © 1999-2006, Apache Software Foundation.
-Licensed under the Apache License, Version 2.0. -
- - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/codes.html b/docs/codes.html deleted file mode 100644 index 5819ee4c3b..0000000000 --- a/docs/codes.html +++ /dev/null @@ -1,280 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - Log4j project - Log4j error codes - - - - - - - - - - - -
-
- -
-

Log4j error messages and their meanings

-

Ceki Gülcü
- November 2004, last updated on December 17th, 2004

-
- - - -
- - - -
- -

Given syntactical flexiblilty that - JoranConfigrator supports, it is no longer - possible to express this syntatical range with a DTD. Thus, - new log4j configuration files in XML should follow the general - template. -

- -

Good:

- -
<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE configuration>
-
-<configuration xmlns='http://logging.apache.org/'>
-  ...
-</configuration>
-        
- -

However, JoranConfigurator will continue to - parse your old XML configuration files which previously - required a reference to log4j.dtd. Thus, altough - deprecated, the following form will continue to be parsed - correctly. -

- -

Deprecated:

- -
<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
-
-<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
-  ...
-</log4j:configuration>
-        
- - -

Using this deprecated form will generate the above mentioned - error message along with an error from the XML parser. -

- - -
- -
- -

The FileNamePattern option for both - TimeBasedRollingPolicy and - FixedWindowRollingPolicy is mandatory. -

- -
- -
- -

Whereas the order of declatation of appenders did not - matter in log4j 1.2, in log4j version 1.3 and later, any - appender referenced at a given point must have been already - declared above that point. In practice though, only - configuration files declaring an AsyncAppender - may be affected by this change and only if the appenders - embeded in th AsyncAppender are declared below it - instead of being declared above it. -

- -

For example, the following config file will no longer work.

- -

Bad:

- -
<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE log4j:configuration>
-
-<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
-
-  <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
-    <appender-ref ref="FILE" />
-  </appender>
-
-   <appender name="FILE" class="org.apache.log4j.FileAppender">
-    <param name="File" value="myapp.log"/>
-    ...
-  </appender>
-
-  <root>
-    <level value ="debug" />
-    <appender-ref ref="ASYNC" />
-  </root>
-
-</log4j:configuration>
-        
- -

It should be changed to the following form.

- -

Good:

- -
<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE configuration>
-
-<configuration xmlns='http://logging.apache.org/'>
-
-   <appender name="FILE" class="org.apache.log4j.FileAppender">
-     <param name="File" value="myapp.log"/>
-      ...
-   </appender>
-
-  <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
-    <appender-ref ref="FILE" />
-  </appender>
-
-  <root>
-    <level value ="debug" />
-    <appender-ref ref="ASYNC" />
-  </root>
-</configuration>
-        
- - - -
- - - - -
- Copyright © 1999-2006, Apache Software Foundation.
-Licensed under the Apache License, Version 2.0. -
- - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/contributors.html b/docs/contributors.html deleted file mode 100644 index 44aea7df11..0000000000 --- a/docs/contributors.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - Log4j project - Log4j Contributors - - - - - - - - - - - -
-
- -

Log4j contributors

-

Log4j is the result of contributions from several dozen - developers and hundreds of users across the globe. Some of the - more prominent contributors are listed below in alphabetical - order. -

-
    - - - - - -
  • Curt Arnold - -

    Curt is an independent software developer and current Logging Services PMC chair. - Curt developed the test framework for the W3C DOM test suites and has contributed to the - Apache Ant, Apache Xerces, Apache Batik, JSUnit, ArgoUML and ant-contrib - projects.

    -
  • - -
  • Mathias Bogaert - -

    While not lurking on the serverside, - Mathias mends the log4j documentation.

    -
  • - -
  • James P. Cakalic -

    Jim is the original author of the PatternLayout and the - NTEventLogAppender. -

    -
  • - -
  • Paul Glezen - -

    Paul maintains the log4j extension manual while he is not - consulting for IBM. -

    -
  • - -
  • Ceki Gülcü - - - - - -

    Ceki is the founder the log4j project which - continues to occupy much of his time. He enjoys writing - software altough he is discovering that it is far more - difficult than what it may seem initially. He is also - managing his IT services - company.

    -
  • - -
  • Jacob Kjome - -

    Jacob Kjome has been developing software - since 1997 and has been playing with Java for about 4 years. - Jake joined the log4j team after being very active on the - user list and contributing servlet and repository selector - related code to the logj-sandbox. He is also a committer on - the (non-Apache related) XMLC, BarracudaMVC, and Prevayler - projects. Of late his free time has been squeezed with a - new job and his vigorous 2 year old son, Nicholas, but he - still tries to pitch in when he can. :-) -

    -
  • - - -
  • Anders Kristensen - -

    Contributor of many enhancements, Anders takes a keen - interest in log4j and all things Java, OO, and XML. He is - currently specification lead for JSR 116, the SIP Servlet - expert group. -

    -
  • - -
  • Jim Moore -

    Jim is often seen answering tough question from log4j - users. -

    -
  • - -
  • Yoav Shapira - - - - -
    -

    Yoav Shapira works for Millennium Pharmaceuticals and - is as interested in the business aspects of Open-Source - Software as he is in the technical aspects. Yoav contributes - to the Tomcat container, the Log4j logging system, and a - number of jakarta-commons and other open-source projects. -

    -
    -
  • - -
  • Jon Skeet - -

    Jon is a software developer in his mid-twenties living in - the UK. He is a Java enthusiast and very active participant - in the comp.lang.java.* newsgroups as well as a moderator - for the log4j mailing lists. He is a committer for the Ant - project, involved (when time permits!) in tidying up the - code documentation. -

    -
  • - -
  • Paul Smith - - - - -
    -

    Paul Smith has been developing software since 1990, and playing - computer games a few years longer than that. He has been thoroughly - enjoying Java since 1998 after he gave up on Visual Basic in disgust. - Paul joined the log4j team after finding how darn useful it and the - companion Chainsaw application was in '03, and has been helping out - where he can, working on Chainsaw v2, and generally making a good - nuisance of himself. -

    - - -
  • - - -
  • Chris Taylor - -

    Chris is the author NTEventLogAppender. In around 1832, - he ported our previous GNU-make build system to at the time - unknown but promising jakarta-ant. -

    -
  • - -
  • Mark Womack - - - - -
    -

    Mark Womack has been developing software for over 13 - years. He has been developing in Java for the past 5 years, - focusing on web application development. He has been an - active committer for the log4j project since April 2002, contributing - features for the upcoming v1.3 release. He is also a member of the Logging - Services PMC.

    -
    -
    -
  • -
- - - -
- - - - - - -
- Copyright © 1999-2006, Apache Software Foundation.
-Licensed under the Apache License, Version 2.0. -
- - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/css/.cvsignore b/docs/css/.cvsignore deleted file mode 100644 index 809f1c22d5..0000000000 --- a/docs/css/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -site.css diff --git a/docs/css/README.txt b/docs/css/README.txt deleted file mode 100644 index 27dbcb5170..0000000000 --- a/docs/css/README.txt +++ /dev/null @@ -1,10 +0,0 @@ - -The eventTable-VERSION.css cascading style sheet files are accessed -by many users when they browse an html file generated by HTMLLayout. - -By convention, the location for the eventTable-VERSION.css files is: - - http://logging.apache.org/logging/log4j/docs/css/ - - - \ No newline at end of file diff --git a/docs/css/eventTable-1.0.css b/docs/css/eventTable-1.0.css deleted file mode 100644 index 9365cbd17f..0000000000 --- a/docs/css/eventTable-1.0.css +++ /dev/null @@ -1,76 +0,0 @@ - -table { - margin-left: 2em; - margin-right: 2em; - border-left: 2px solid #AAA; -} - -TR.even { - background: #FFFFFF; -} - -TR.odd { - background: #DADADA; -} - -/* -TR.WARN TD, TR.ERROR TD, TR.FATAL TD { - border-bottom: 1px solid #F00; - border-top: 1px solid #F00; - font-weight: bold; -} -*/ - -TR.warn TD.level, TR.error TD.level, TR.fatal TD.level { - font-weight: bold; - color: #FF4040 -} - -TD { - padding-right: 1ex; - padding-left: 1ex; - border-right: 2px solid #AAA; -} - -/* -TD:first-child { - border-left: 2px solid #AAA; -} */ - -TD.time, TD.date { - text-align: right; - font-family: "Courier New", courier, monospace; - font-size: smaller; -} - -TD.sn { - text-align: right; - width: 5ex; - font-family: "Courier New", courier, monospace; - font-size: smaller; -} - -TD.thread { - text-align: left; -} - -TD.level { - text-align: right; -} - -TD.logger { - text-align: left; - font-size: smaller; -} - -TR.header { - background: #9090FF; - color: #FFF; - font-weight: bold; - font-size: larger; -} - -TD.exception { - background: #C0C0F0; - font-family: "Courier New", courier, monospace; -} \ No newline at end of file diff --git a/docs/css/site.css b/docs/css/site.css deleted file mode 100644 index 149f6c0dd7..0000000000 --- a/docs/css/site.css +++ /dev/null @@ -1,140 +0,0 @@ - -H1, H2, H3 { - color: #101099; -} - -A:link, A:visited { - text-decoration: none; - color: #006699; -} - -A:link:hover { - text-decoration: underline; -} - -.centercol { - margin-top: 120px; - margin-left: 210px; - margin-right:210px; - max-width: 800px; -} - -.leftcol { - position: absolute; - left: 10px; - top: 130px; - width: 190px; -} - -.banner { - position: absolute; - left: 10px; - top: 10px; - height: 130px; - width: 1000px; -} - -.menu_header, .menu_item { -/* width: 190px; */ - font-family: "trebuchet MS", Arial, Helvetica, sans-serif; - font-size: smaller; -} - -.menu_header { - border:1px solid #AAAAAA; - background: #CCCCCC; - padding-left: 1ex; -} - -.menu_item:hover { - background: #DDD; -} - -.menu_item { - background: #EEEEEE; - padding-left: 2ex; - border-top: 0px solid #AAAAAA; - border-right: 1px solid #AAAAAA; - border-bottom:1px solid #AAAAAA; - border-left: 1px solid #AAAAAA; -} - -.source { - border-top: 1px solid #DDDDDD; - border-bottom: 1px solid #DDDDDD; - background:#eee; - font-family: Courier, "MS Courier New", Prestige, Everson Monocourrier, monospace; - font-size: smaller; - padding-bottom: 0.5ex; - padding-top: 0.5ex; - padding-left: 2ex; -} - -table.ls { - background: #FFFFFF; -} -table.ls td { - background: #f4f4f4; - vertical-align: top; - padding-bottom: 1ex; -} - -table.ls th { - background: #E4E4E4; -} - -.index-faqSection { - font-size: larger; - padding-left: 0em; - font-weight: bolder; -} -.index-question { - padding-left: 1em; -} - -.faqSection { - font-size: larger; - font-weight: bolder; -} - -.question { - font-weight: bolder; -} - -/* this class is used for screen output placed in
 tags */
-.screen_output {
-  padding-left:  1em;
-  padding-right: 1em;
-  border-top:   1px solid #AAAAAA;
-  border-right: 1px solid #AAAAAA;
-  border-bottom:1px solid #AAAAAA;
-  border-left:  1px solid #AAAAAA;
-}
-
-
-.big {
-  font-size: larger;
-  font-weight: bold;
-}
-
-.small {
-  font-size: smaller;
-}
-
-.red {
-  color: #AA0000;
-}
-
-.msg_title {
-  padding-left:  1ex;
-  padding-right: 1ex;
-  font-family: Courier, "MS Courier New", Prestige, Everson Monocourrier, monospace;
-  border:   1px solid #AAAAAA;
-  background: #DDDDFF;
-
-}
-
-.msg_meaning {
-  padding-left:  1em;
-  padding-right: 1em;
-}
diff --git a/docs/documentation.html b/docs/documentation.html
deleted file mode 100644
index 298fca037b..0000000000
--- a/docs/documentation.html
+++ /dev/null
@@ -1,268 +0,0 @@
-
-
-
-
-    
-    
-    
-        
-
-    
-    
-    
-    
-    
-        
-            
-
-                                                    
-            
-                                        
-            
-            
-            
-                                    
-                         
-            
-                                   
-
-            Log4j project - Documentation
-        
-
-                
-            
-                     
-     
-       
-     
-   
-               
-
-	   
-
- -

log4j documentation

- - -

Translations

- -

Articles on log4j

- -

Log4j presentations

- -

Training & Professional support

-

The following organisations offer log4j-related consultancy - and training services. Their inclusion on this page does - not imply endorsement by the Apache Software Foundation. -

- - -

If you would like your log4j-related article or service - to be listed here, then please send a note to the log4j-user@logging.apache.org - list. -

- - - -
- - - - - - -
- Copyright © 1999-2006, Apache Software Foundation.
-Licensed under the Apache License, Version 2.0. -
- - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/download.html b/docs/download.html deleted file mode 100644 index ba075b8298..0000000000 --- a/docs/download.html +++ /dev/null @@ -1,450 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Log4j project - Download - - - - - - - - - - - -
-
- -

log4j version 1.2.14

-

Log4j is available - for download from a number of mirrors. Please - use these mirrors as they improve download time and save - bandwidth. -

-

Changes in log4j 1.2.14: -

    -
  • AsyncAppender was rewritten to eliminate reported deadlocks (bugs 26224, 28006, 37904, 38137), - and to add an option to not block if the event queue becomes full (bug 38982).
  • - -
  • SyslogAppender can now accept a port specification (bug 39687) in its syslogHost attribute.
  • - -
  • SMPTAppender can now accept cc and bcc addresses (bug 19125) and perform password authentication (bug 24969).
  • - -
  • The following bugs were fixed: -
      -
    • 40159: NullPointerException in org.apache.log4j.NDC.get. -
    • 36787: org.apache.log4j.lf5.util.DateFormatManager.setTimeZone assignment error. -
    • 38559: Monthly logs not generated at midnight with DailyRollingFileAppender. -
    • 40145: PatternLayout specifier %r is not consistent with documentation. -
    • 37119: Space after log level causes default level to be used. -
    • 39135: Bad patterns in ISO8601DateFormat and DateTimeDateFormat. -
    • 35743: SyslogAppender throws NullPointerException upon misconfiguration. -
    • 15501: FallbackErrorHandler throws NullPointerException if no loggers are set. -
    • 38564: Bad documentation for WriterAppender.encoding. -
    • 37866: NTEventLogAppender not build, tested and placed in distribution. -
    • 38662: SMTPAppender does not output newlines between stack trace lines. -
    • 30294: SMTPAppender will not run within sandbox. -
    • 16922: MDC with SMTPAppender doesn't work. -
    • 31507: Misspelling in HierarchyDynamicMBean. -
    • 35123: Additivity not exported by PropertyPrinter. -
    • 31003: RollingFileAppender, if removed, can cause NullPointerExceptions. -
    • 23021: AsyncAppender blocks on thread death. -
    • 40412: NOTICE file added to distribution and jar. -
    • 40378: Chainsaw of log4j 1.2 does not show TRACE level. -
    • 40501: TRACE level missing in short introduction to log4j. -
    • 37960: Update site generation to velocity 1.4 and remove dependency on logging/site project. -
    -
  • -
-

-

The next major release of log4j will be version 1.3. It will contain - many new features and changes, and if you have written custom code, it may - need to be modified to work with it. Please see the document entitled preparing - for log4j 1.3 for a more detailed discussion. -

-

Earlier Releases

-

We also maintain earlier - versions of log4j for download, intended for the - curious paleontologist -- there seems to be quite a few - of them! -

-

Third-party extensions (listed in alphabetical order)

-
- - -
DatedFileAppender
- -
DatedFileAppender works in the same manner as - the Tomcat FileLogger. Contrary to - DailyRollingFileAppender shipping with log4j, log - file names generated by DatedFileAppender always - contain today's date. While this distinction seems minor, it - means you can reliably copy, compress, remove or manipulate a - day's log file shortly after midnight. With the - DailyRollingFileAppender, a day's log file is not - renamed until the first message is logged some time after - midnight. -
- - - -
- JDBCAppender -
- -
A powerful JDBCAppender by Danko Mannhaupt - who continues the work of Thomas Fenner. You might find - this JDBCAppender more suitable then the one that ships with - log4j 1.2. -
- - - -
- Just4log -
- -
Just4Log is a library to enhance dynamically the - performance of various logging systems inside a java - application. Dynamically because the sourcecode in java is not - modified but rather the optimization occurs on the compiled - ByteCode files. -
- - -
log4Ant
- -
log4Ant includes a complete bridge to the Log4J logging systemfor a robust build monitoring system. - These Ant components let you capture, map, and send Ant log messages and stdio output through your Log4J installation. Contact contact@jware.info -
- - -
log4j400
- -
Log4J400 includes MessageQueue and DataQueue Appenders for - the AS/400 (aka IBM iSeries). -
- - - -
log4j2db
- -
This Project provides a set of EJBs to store Log4J events - (received via JMS appender) in a database. The main aim is to - provide a toolset for a centralized, data-center suitable - logging. -
- - - -
log4jME
- -
Log4jME, or log4j MiniEdition, is based on the - same code as log4j. However, as the name indicates the - mini-edition is much smaller. It offers the same client - interface such that code compiled for log4jME is - compatible with log4j standard edition. You can choose to - upgrade to log4j standard edition at any time by replacing - log4jME.jar with log4j.jar in your - classpath. At this time, log4jME is only available through - ASF Subversion repository in the Logging Services Sandbox. -
- - - -
log4Unit
- -
Log4Unit is a JUnit extension - combining JUnit with Log4J. The intention is to create test - protocols for JUnit. - -

JUnit is asymmetrical in the sense that it focusses on the - documentation of test failures and errors. Successful - execution of a test case is not further documented. In order - to obtain a test protocol that documents the initial settings, - the test case execution and its results, a logging component - is required. Log4J as the current de facto standard is - selected for this extension. -

-
- - - -
Log4Web (commercial)
- -
Log4Web is a J2EE web application, designed to web-enable - system log files that have been generated by log4j. -
- - - -
- Log Tag -
-
A custom log tag library from the Jakarta - Taglibs project.
- - - -
LogWeb
- -
LogWeb is a web interface for configuring log4j at runtime - within a servlet container. Every log4j feature of is - configurable through this interface. -
- - - - -
- SNMPTrapAppender -
- -
An appender to send formatted logging event strings to a - specified managment host (typically, a MLM of some sort, but - could also be an SNMP management console) in the form of an - SNMP trap. -
- - - -
XpoLog -
- -
Log view and analysis application which enables web - browsing and analysis over logs. -
- - - -
-

Ports to other languages (listed in alphabetical order within each section)

-

Fellow Apache Logging Services Projects

-
- - -
log4cxx
-
Log4cxx is a port to C++ of the log4j project.
- - -
log4net
- -
The .NET implementation of the popular log4j Java API - providing flexible and arbitrarily granular control over log - management and configuration.
- - -
log4php
- -
Log4Php is a PHP port of log4j framework. It supports xml configuration, - logging to files, stdout/err, syslog, socket, configurable - output layouts and logging levels.
- -
-

Other Ports

-
- -
log4c
- -
ANSI C functions and macros for flexible logging to files - and other destinations. It is modeled after log4j. It follows - the log4j API within the limits of reason. Intended for use in time-space - critical environments.
- - - -
log4cpp
-
A library of C++ classes for flexible logging to files, - syslog, IDSA and other destinations modeled after log4j.
- - - -
log4cplus
-
Log4cplus is a simple to use C++ logging API providing - thread-safe, flexible, and arbitrarily granular control over - log management and configuration. It is modeled after the Java - log4j API.
- - - -
log4E
- -
The Goanna project (Eiffel Web Services) now includes - log4E, a complete port of log4j. -
- - -
Log::Log4perl
- -
Log::Log4perl is a Perl port of log4j by Kevin Goess and - Mike Schilli. The authors made sure that their port was as - close as possible to the original implementation. Even the - configuration files are similar! The project is still being - enhanced, however the current release is stable and has been - released to CPAN. -
- - -
log4LS
- -
Log4LS is a LotusScript library package and is used to get - logging statements to a Domino database, sent by mail or - written to a file. It is modeled after Jakarta log4j. -
- - -
log4py
- -
Log4Py is a python logging module similar to log4j. It - supports logging to files or to stdout/stderr, variable - log-levels, configurable output formats and configuration via - configuration files. -
- - - -
log4p
-
Another Python translation of log4j. This project no - longer seems to be maintained.
- - - -
log4plsql
- -
Log4plsql is a Oracle PL/SQL logging module similar to - log4j. It supports logging out-off transaction. It is useful - for logging, benchmarking and monitoring PL/SQL applications. -
- - - -
qmmslog
- -
Qmmslog is a port of log4j to the Qt/C++ platform. -
- - -
log4r
-
A Powerful Logger for Ruby. -

Log4r features an extremely flexible logging library for - Ruby. Killer features include a heiarchial logging system - of any number of levels, logger inheritance, multiple - output destinations, tracing, custom formatting and more. - Log4r was inspired by log4j. Log4r provides the defining - features of log4j and some of its own features that just - might make log4j users envious.

-
- - -
-

If you would like your software to be listed here, then send a note to the log4j-user@logging.apache.org - list.

- - - -
- - - - - - -
- Copyright © 1999-2006, Apache Software Foundation.
-Licensed under the Apache License, Version 2.0. -
- - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/earlier.html b/docs/earlier.html deleted file mode 100644 index d675ff228a..0000000000 --- a/docs/earlier.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - Log4j project - Older distributions - - - - - - - - - - - -
-
- -

Older distributions of the log4j package

-
-

BEWARE:Certain Internet Explorer versions rename .tar.gz downloads - as .tar. You should rename the files back to - tar.gz after the download completes. -

-
- Log4j Archives - - - -
- - - - - - -
- Copyright © 1999-2006, Apache Software Foundation.
-Licensed under the Apache License, Version 2.0. -
- - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/faq.html b/docs/faq.html deleted file mode 100644 index fd0a4e0ccd..0000000000 --- a/docs/faq.html +++ /dev/null @@ -1,1898 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - Log4j project - Frequently Asked Questions about log4j - - - - - - - - - - - -
-
- -
- -

Frequently Asked Questions about log4j

- -

Ceki Gülcü, Paul Smith, Chris Taylor
- - May 2002, last updated on September 15th, 2004

- -
- - - -
-
- Section 1. Generalities -
- - - - -
Question 1.1What is log4j?
- - - -
Question 1.2Is log4j a reliable logging system?
- - - -
Question 1.3What are the prerequisites for log4j?
- - - -
Question 1.4What are the features of log4j?
- - - -
Question 1.5Is there example code for using log4j?
- - - -
Question 1.6What documentation should I read to learn more about - - log4j?
- - - -
Question 1.7Is log4j thread-safe?
- - - -
Question 1.8What does log output look like?
- - - -
Question 1.9Why should I use log4j when JDK 1.4 already ships with a - - logging API?
-
-
- Section 2. Using log4j -
- - - - -
Question 2.1What are Loggers?
- - - -
Question 2.2How can I change log behavior at runtime?
- - - -
Question 2.3What is the fastest way of (not) logging?
- - - -
Question 2.4 Are there any suggested ways for naming loggers?
- - - -
Question 2.5How do I get the fully-qualified name of a class in a static block?
- - - -
Question 2.6Can the log output format be customized?
- - - -
Question 2.7What are the configurable options for FooBarAppender?
- - - -
Question 2.8What is the recommended way of migrating from - - java.util.logging to log4j?
- - - -
Question 2.9Is it possible to direct log output to - - different appenders by level?
- - - -
Question 2.10What does the Windows NT Event Viewer complain about - - missing descriptions for my event messages when I use the - - NTEventLogAppender?
- - - -
Question 2.11Why can't I map my logger names to the loggers that - - appear in the NT Event Log when I use the - - NTEventLogAppender?
- - - -
Question 2.12Are there suggested approaches for logging in JSP pages?
-
-
- Section 3. Advanced questions -
- - - - -
Question 3.1Can the outputs of multiple client request go to - - different log files?
- - - -
Question 3.2Logger instances seem to be create only. Why isn't - - there a method to remove logger instances?
- - - -
Question 3.3How do I get multiple process to log to the same file?
- - - -
Question 3.4How about the timesamps of events generated by multiple - - processes across multiple hosts (possibly across multiple - - timezones)? - -
- - - -
Question 3.5Why can't log4j find my properties file in a J2EE or WAR - - application?
- - - -
Question 3.6Is there a way to get log4j to automatically reload a - - configuration file if it changes?
-
- - - - - -
Question 4.1Why should I donate my extensions to log4j back to the - - project? - -
- - - -
Question 4.2What should I keep in mind when contributing code?
- - - -
Question 4.3How can I contribute a new question/answer to this - - document?
-
- - -
- Section 1. Generalities -
- - -

This section contains general questions about log4j.

- - - - - -

log4j is a tool to help the programmer output log statements to a - - variety of output targets. - -

- - - -

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 shipped code without - - incurring a high performance cost. It follows that the speed - - of logging (or rather not logging) is capital. - -

- - - -

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 hierarchical loggers. Using loggers it is - - possible to selectively control which log statements are output at - - arbitrary granularity. - -

- - - -

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. - -

- - - - - -

No. log4j is not reliable. It is a best-effort - - fail-stop logging system. - -

- - - -

By fail-stop, we mean that log4j will not throw unexpected - - exceptions at run-time potentially causing your application to - - crash. If for any reason, log4j throws an uncaught exception, - - please send an email to the log4j-user@logging.apache.org - - mailing list. Uncaught exceptions are handled as serious bugs - - requiring immediate attention. - -

- - - -

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. - -

- - - - - -
    - -
  • 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. - -

  • - - - -
  • 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. - -

    - -

    The DOMConfigurator.configure(String filename) method and its - - variants require a JAXP compatible XML parser, for example Xerces or Sun's - - parser. Compiling the DOMConfigurator requires the presence of a - - JAXP parser in the classpath. - -

    - -
  • - - - -
  • The org.apache.log4j.net.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. - -

  • - - - -
  • The org.apache.log4j.net.JMSAppender - - requires the presence of the JMS API as well as JNDI. - -

  • - - - -
  • log4j test code relies on the JUnit testing framework. - -

  • - -
- - - - - -
    - - - -
  • log4j is optimized for speed.

  • - - - -
  • log4j is based on a named logger hierarchy.

  • - - - -
  • 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. - -

  • - - - -
  • log4j is thread-safe.

  • - - - -
  • log4j is not restricted to a predefined set of - - facilities.

  • - - - -
  • Logging behavior can be set at runtime using a - - configuration file. Configuration files can be property - - files or in XML format.

  • - - - -
  • log4j is designed to handle Java Exceptions from the - - start.

  • - - - -
  • log4j can direct its output to a file, the console, - - an java.io.OutputStream, - - java.io.Writer, 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.

  • - - - -
  • log4j uses 6 levels, namely TRACE, DEBUG, INFO, WARN, - - ERROR and FATAL.

  • - - - -
  • The format of the log output can be easily changed by - - extending the Layout - - class.

  • - - - -
  • The target of the log output as well as the writing - - strategy can be altered by implementations of the - - Appender interface.

  • - - - -
  • log4j supports multiple output appenders per logger. - -

  • - - - -
  • log4j supports internationalization.

  • - -
- - - - - -

See the examples/ directory.

- - - - - -

Make sure to read the short - - manual. It is also recommended to you read The complete - - log4j manual which is much more detailed and up to - - date. Both documents were written by Ceki Gülcü. - -

- - - - - -

Yes, log4j is thread-safe. Log4j components are designed to - - be used in heavily multithreaded systems.

- - - - - - - -

The log output can be customized in many ways. Moreover, - - one can completely override the output format by implementing - - one's own Layout. - -

- - - -

Here is an example output using PatternLayout with - - the conversion pattern "%r [%t] %-5p %c{2} %x - %m%n" - -

- - - -
-
-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.
-
-276 [main] DEBUG SortAlgo.SWAP i=1 j=0 - Swapping intArray[0] = 1 and intArray[1] = 0
-
-290 [main] DEBUG SortAlgo.OUTER i=0 - Outer loop.
-
-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.
-
-	
- - - -

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 nested diagnostic - - context (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. - -

- - - - - -

- - 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. - -

- - - -

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. - -

- - -
- Section 2. Using log4j -
- - -

This section contains answers to questions encountered while - - using log4j.

- - - - - -

Lggers lie at the heart of log4j. Loggers define a hierarchy and give - - the programmer run-time control on which statements are - - printed or not. - -

- - - -

Loggers are assigned levels. A log statement is printed - - depending on its level and its logger. - -

- - - -

Make sure to read the log4j manual - - for more information. - -

- - - - - -

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. - -

- - - -

The PropertyConfigurator defines a particular format - - of a configuration file. See also the examples/Sort.java - - example and associated configuration files. - -

- - - -

Configuration files can be specified in XML. See - - log4j.dtd and - - org.log4j.xml.DOMConfigurator for more details. - -

- - - -

See the various Layout and Appender components for specific - - configuration options. - -

- - - -

In addition to configuration files, the user may disable all - - messages belonging to a set of levels. See next item. - -

- - - - - - - -

For some logger l, writing, - -

- - - -
-
- l.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
-
-	
- - - -

incurs the cost of constructing the message parameter, that is - - converting both integer i and entry[i] to a - - String, and concatenating intermediate strings. This, regardless of - - whether the message will be logged or not. - -

- - - -

If you are worried about speed, then write

- -
-
-   if(l.isDebugEnabled()) {
-
-     l.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
-
-   }
-
-	
- - - -

This way you will not incur the cost of parameter - - construction if debugging is disabled for logger - - l. 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 - - debugEnabled and once in debug. - - This is an insignificant overhead since evaluating a logger - - takes less than 1% of the time it takes to actually log a - - statement. - -

- - - -

Better alternative based on message patterns

- -

As of log4j version 1.3, there exists a significantly more - - convenient alternative based on message patterns. Assuming - - entry is an object, you can write: - -

- - - -

- - l.debug("The new entry is {}.", entry); - -

- - - -

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 - - entry. In other words, the paramerized form does - - not incur the cost of parameter construction in case the log - - statement is disabled. - -

- - - -

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 disabled logging - - statement. - -

- - - -

- - l.debug("The new entry is "+entry+".");
- - l.debug("The new entry is {}.", entry); - -

- - - -

A two argument variant is also availalble. For example, you - - can write: - -

- -

- - l.debug("The new entry is {}. It replaces {}.", entry, oldEntry); - -

- - - - - - - - - - - - - - - -

Yes, there are.

- - - -

You can name loggers by locality. 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: - -

- - - -
    - -
  • It is very simple to implement.
  • - - - -
  • It is very simple to explain to new developers.
  • - - - -
  • It automatically mirrors your application's own modular design. - -
  • - -
  • It can be further refined at will.
  • - - - -
  • Printing the logger automatically gives information on the locality - - of the log statement.
  • - -
- - - -

However, this is not the only way for naming loggers. A - - common alternative is to name loggers by functional - - areas. For example, the "database" logger, "RMI" - - logger, "security" logger, or the "XML" logger. - -

- - - -

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". - -

- - - -

You are totally free in choosing the names of your - - loggers. The log4j package merely allows you to manage your - - names in a hierarchy. However, it is your responsibility to define - - this hierarchy. - -

- - - -

Note by naming loggers by locality one tends to name things by - - functionality, since in most cases the locality relates closely to - - functionality. - -

- - - - - - - -

You can easily retrieve the fully-qualified name of a class in a - - static block for class X, with the statement - - X.class.getName(). Note that X is the class - - name and not an instance. The X.class statement does - - not create a new instance of class X. - -

- - - -

Here is the suggested usage template:

- - - -
-
-package a.b.c;
-
-
-
-public class Foo {
-
-  final static Logger logger = Logger.getLogger(Foo.class);
-
-  ... other code
-
-
-
-}
-
-	
- - - - - -

Yes, you can extend the Layout class to create - - you own customized log format. Appenders can be parameterized - - to use the layout of your choice. - -

- - - - - -

Log4j uses JavaBeans style configuration.

- - - -

Thus, any setter method in FooBarAppender - - corresponds to a configurable option. For example, in RollingFileAppender - - the setMaxBackupIndex(int - - maxBackups) method corresponds to the - - maxBackupIndex option. The first letter of the - - option can be upper case, i.e. MaxBackupIndex - - and maxBackupIndex are equivalent but not - - MAXBACKUPIndex nor mAXBackupIndex. - -

- - - -

Layouts options are also defined by their setter methods. The same goes - - for most other log4j components. - -

- - - - - - - -

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. - -

- - - -

If you're on a Win32 platform, we recommend Textpad. 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! :) - -

- - - - - -

Yes it is. Setting the Threshold option of any appender - - extending AppenderSkeleton, - - (most log4j appenders extend AppenderSkeleton) to filter out all log - - events with lower level than the value of the threshold - - option. - -

- - - -

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. - -

- - - -

This policy usually best encapsulates what the user - - actually wants to do, as opposed to her mind-projected - - solution. - -

- -

See examples/sort4.lcf for an example threshold - - configuration.

- - - -

If you must filter events by exact level match, then you can - - attach a LevelMatchFilter - - to any appender to filter out logging events by exact level match. - -

- - - - - - - -

The NT Event Viewer relies on message resource 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. - -

- - - - - - - -

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... - -

- - - - - -

- - 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 <% ... %> statements - - as indicated in the Short Manual and the rest of the documentation. - -

- -

- - However, if your design calls for a minimum amount of Java in your JSP - - pages, consider using the - - Log Taglib - - from the Jakarta Taglibs project. It provides logging JSP tags that invoke - - log4j. - -

- - -
- Section 3. Advanced questions -
- - -

This section contains answers to more advanced questions about log4j.

- - - - - - - -

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. - -

- - - -

It is simpler to use a nested diagnostic context - - (NDC). Typically, one would NDC.push() 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. - -

- - - -

See the NDC and the PatternLayout - - classes for more information. The NumberCruncher - - example shows how the NDC can be used to distinguish the log - - output from multiple clients even if they share the same log - - file. - -

- - - -

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. - -

- - - - - - - -

It is quite nontrivial to define the semantics of a - - "removed" logger escecially if it is still referenced by the - - user. Future releases may include a remove method in - - the Logger class.

- - - - - -

You may have each process log to a - - SocketAppender. - - The receiving - - SocketServer - - (or - - SimpleSocketServer) - - can receive all the events and send them to a single - - log file. - -

- - - - - - - -

The timestamp is created when the logging event is created. - - That is so say, when the debug, - - info, warn, error or - - fatal method is invoked. Thus, the timestamp is - - unaffected by the time at which event arrive at a remote - - socket server. - -

- - - -

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. - -

- - - - - - - -

The short answer: the log4j classes and the properties file - - are not within the scope of the same classloader. - -

- - - -

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. - -

- - - -

Log4j only uses the default Class.forName() - - mechanism for loading classes. Resources are handled - - similarly. See the documentation for - - java.lang.ClassLoader for more details. - -

- - - -

So, if you're having problems, try loading the class or - - resource yourself. If you can't find it, neither will - - log4j. ;) - -

- - - - - - - -

Yes. Both the DOMConfigurator and the PropertyConfigurator support - - automatic reloading through the configureAndWatch method. - - See the API documentation for more details. - -

- - - - - -

Because the configureAndWatch launches a - - separate wathdog thread, and because there is no way to stop - - this thread in log4j 1.2, the configureAndWatch - - method is unsafe for use in J2EE envrironments where - - applications are recycled. - -

- - - - -
- Section 4. Contributing to the project -
- - -

This section includes questions about contributing to the - - project

- - - - - -

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. You are free to do - - whatever you wish with your proprietary log4j extensions. - - In particular, you may choose to never release your extensions - - to the wider public. - -

- - - -

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 n, then when log4j - - release version n+1 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. - -

- - - -

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. - -

- - - - - -
    - - - -
  1. - -

    Write a test case for your contribution.

    - - - -

    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. - -

    - -
  2. - - - - - -
  3. - -

    Stick to the existing indentation style even if you hate it.

    - - - -

    Alternating between indentation styles makes it hard to - - understand the source code. Make it a little harder on - - yourself but easier on others. - -

    - - - -

    Log4j has adopted a rather conservative approach by - - following the Code Conventions - - for the JavaTM Programming Language. We use 2 (two) - - spaces for indentation and no tabs. - -

    - -
  4. - - - -
  5. - -

    Please do not both modify the code and change the - - indentation in a single commit.

    - - - -

    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. - -

    - - - -

    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. - -

    - - - -
  6. - -
  7. - -

    Make every effort to stick to the JDK 1.1 API.

    - - - -

    One of the important advantages of log4j is its - - compatibility with JDK 1.1.x. - -

    - -
  8. - - - -
  9. - -

    Always keep it simple, small and fast when - - possible.

    - - - -

    It's all about the application not about logging.

    - -
  10. - - - -
  11. - -

    Identify yourself as a contributor at the top of the - - relevant file. - -

    - -
  12. - -
  13. - -

    Take responsibility for your code.

    - - - -

    Authoring software is very much like running a marathon. It - - takes time and endurance. - -

    - -
  14. - -
  15. - -

    Did we mention sticking with the indentation style?

    - -
  16. - -
  17. Did we mention writing test cases?

    - -
  18. - - - -
- - - - - -

Log4j uses velocity-anakia - - to generate its web-site, including this FAQ. We have devised - - special macros to help us automatically generate labeled - - question/answer pairs. - -

- - - -

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. - -

- - - -

If you are a committer, then you must edit the - - /src/xdocs/faq.xml file. The format of the file - - should be self-evident. After you have made your changes, run - - the command - -

- -
ant site
- - - -

After the appropriate transformation, your changes should - - appear in the file /docs/faq.html. - -

- - - - - - -
- Copyright © 1999-2006, Apache Software Foundation.
-Licensed under the Apache License, Version 2.0. -
- - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/history.html b/docs/history.html deleted file mode 100644 index dcb4186f9e..0000000000 --- a/docs/history.html +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - Log4j project - Project history - - - - - - - - - - - -
-
- -

Project history

-

The project history gives a - brief summary of changes and additions. Users frequently - report bugs that are solved in newer versions of log4j. Please - have a look at the history file before asking for help. -

-

The project's official URL is http://logging.apache.org/log4j. -

-

Many thanks to all the log4j users who keep sending us input - and sometimes even praise for our collective effort. The first - ancestor of log4j was written for the E.U. sponsored SEMPER project. N. Asokan, - Ceki Gülcü and Michael Steiner came up with the idea - of hierarchical loggers back in 1996. Their idea is still at the - heart of log4j. The package was considerably improved over the - years at the IBM Zurich - Research Laboratory. However, log4j is no longer associated - nor supported by IBM. -

-

Special thanks to M. Niksch from ZRL for his assistance on - many large and small matters. The Apache members, Pier - Fumagalli and Sam Ruby in particular, have been extremely - helpful in easing the move to Apache. -

-

The log4j logo was designed and kindly donated by Cyberlab SA of Switzerland. -

- - - -
- - - - - - -
- Copyright © 1999-2006, Apache Software Foundation.
-Licensed under the Apache License, Version 2.0. -
- - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/images/ceki-72x101.gif b/docs/images/ceki-72x101.gif deleted file mode 100644 index 7c7f002cfe..0000000000 Binary files a/docs/images/ceki-72x101.gif and /dev/null differ diff --git a/docs/images/chainsaw-fullscreen-small.jpg b/docs/images/chainsaw-fullscreen-small.jpg deleted file mode 100644 index e4de51fcdb..0000000000 Binary files a/docs/images/chainsaw-fullscreen-small.jpg and /dev/null differ diff --git a/docs/images/chainsaw-fullscreen.jpg b/docs/images/chainsaw-fullscreen.jpg deleted file mode 100644 index 14835d1fd6..0000000000 Binary files a/docs/images/chainsaw-fullscreen.jpg and /dev/null differ diff --git a/docs/images/coverSmall.png b/docs/images/coverSmall.png deleted file mode 100644 index 4b19db90e5..0000000000 Binary files a/docs/images/coverSmall.png and /dev/null differ diff --git a/docs/images/cyberlab15.gif b/docs/images/cyberlab15.gif deleted file mode 100644 index 1856324ba0..0000000000 Binary files a/docs/images/cyberlab15.gif and /dev/null differ diff --git a/docs/images/ecaward_finalist_logo.gif b/docs/images/ecaward_finalist_logo.gif deleted file mode 100644 index 220896b78d..0000000000 Binary files a/docs/images/ecaward_finalist_logo.gif and /dev/null differ diff --git a/docs/images/logo.jpg b/docs/images/logo.jpg deleted file mode 100644 index 5b6ede812f..0000000000 Binary files a/docs/images/logo.jpg and /dev/null differ diff --git a/docs/images/mark-72x99.gif b/docs/images/mark-72x99.gif deleted file mode 100644 index 8d507305f1..0000000000 Binary files a/docs/images/mark-72x99.gif and /dev/null differ diff --git a/docs/images/psmith.jpg b/docs/images/psmith.jpg deleted file mode 100644 index edde7adfe4..0000000000 Binary files a/docs/images/psmith.jpg and /dev/null differ diff --git a/docs/images/yshapira.bmp b/docs/images/yshapira.bmp deleted file mode 100644 index c2f2bddde3..0000000000 Binary files a/docs/images/yshapira.bmp and /dev/null differ diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index a0aa6db4ab..0000000000 --- a/docs/index.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Log4j project - Introduction - - - - - - - - - - - -
-
- -

Introduction

-

Inserting log statements into your code is a low-tech method - for debugging it. It may also be the only way because - debuggers are not always available or applicable. This is - often the case for distributed applications.

-

On the other hand, some people argue that log statements - pollute source code and decrease legibility. (We believe that - the contrary is true). In the Java language where a - preprocessor is not available, log statements increase the - size of the code and reduce its speed, even when logging is - turned off. Given that a reasonably sized application may - contain thousands of log statements, speed is of particular - importance.

-

With log4j it is possible to enable logging at runtime - without modifying the application binary. The log4j package is - designed so that these statements can remain in shipped code - without incurring a heavy performance cost. Logging behavior - can be controlled by editing a configuration file, without - touching the application binary.

-

Logging equips the developer with detailed context for - application failures. On the other hand, testing provides - quality assurance and confidence in the application. Logging - and testing should not be confused. They are - complementary. When logging is wisely used, it can prove to be - an essential tool.

-

One of the distinctive features of log4j is the notion of - inheritance in loggers. Using a logger - hierarchy it is possible to control which log - statements are output at arbitrarily fine granularity but also - great ease. This helps reduce the volume of logged output and - minimize the cost of logging.

-

The target of the log output can be a file, an - OutputStream, a java.io.Writer, a - remote log4j server, a remote Unix Syslog daemon, or many other output targets.

-

On an AMD Duron clocked at 800Mhz running JDK 1.3.1, it costs - about 5 nanoseconds to determine if a logging statement should - be logged or not. Actual logging is also quite fast, ranging - from 21 microseconds using the SimpleLayout, 37 - microseconds using the TTCCLayout. The performance of the - PatternLayout is almost as good as the dedicated layouts, - except that it is much more flexible.

-

The package is being constantly improved thanks to input from - users and code contributed by authors in the community. -

- - - -
- - - - - - -
- Copyright © 1999-2006, Apache Software Foundation.
-Licensed under the Apache License, Version 2.0. -
- - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/install-chainsaw.html b/docs/install-chainsaw.html deleted file mode 100644 index e4d385c8c3..0000000000 --- a/docs/install-chainsaw.html +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - Log4j project - $properties.getChild("title").getText() - - - - - - - - - - - -
-
- - - - -
- - - - - - -
- Copyright © 1999-2006, Apache Software Foundation.
-Licensed under the Apache License, Version 2.0. -
- - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/manual.html b/docs/manual.html deleted file mode 100644 index 94cdea8cb7..0000000000 --- a/docs/manual.html +++ /dev/null @@ -1,1215 +0,0 @@ - - -log4j manual - - - - -
-

Short introduction to log4j

- - Ceki Gülcü -

- March 2002 -
-
- -

- Copyright © 2000-2006, The Apache Software Foundation. - Licensed under the Apache License, Version 2.0. - The present short manual also borrows some text from - "The - complete log4j manual", which contains more detailed - and up to date information, by the same author (yours truly). -

-

Abstract

- -

This document describes the log4j API, its unique features and -design rationale. Log4j is an open source project based on the work of -many authors. It allows the developer to control which log statements -are output with arbitrary granularity. It is fully configurable at -runtime using external configuration files. Best of all, log4j has a -gentle learning curve. Beware: judging from user feedback, it is also -quite addictive. - -

Introduction

- -

Almost every large application includes its own logging or tracing -API. In conformance with this rule, the E.U. SEMPER project decided to write its -own tracing API. This was in early 1996. After countless enhancements, -several incarnations and much work that API has evolved to become -log4j, a popular logging package for Java. The package is distributed -under the Apache Software License, a -fully-fledged open source license certified by the open source initiative. The -latest log4j version, including full-source code, class files and -documentation can be found at http://logging.apache.org/log4j/. -By the way, log4j has been ported to the C, C++, C#, Perl, Python, -Ruby, and Eiffel languages. - -

Inserting log statements into code is a low-tech method for -debugging it. It may also be the only way because debuggers are not -always available or applicable. This is usually the case for -multithreaded applications and distributed applications at large. - -

Experience indicates that logging was an important component of the -development cycle. It offers several advantages. It provides precise -context about a run of the application. Once inserted into -the code, the generation of logging output requires no human -intervention. Moreover, log output can be saved in a persistent medium -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. - -

As Brian W. Kernighan and Rob Pike put it in their truly excellent -book "The Practice of Programming" -

-  As personal choice, we tend not to use debuggers beyond getting a
-  stack trace or the value of a variable or two. One reason is that it
-  is easy to get lost in details of complicated data structures and
-  control flow; we find stepping through a program less productive
-  than thinking harder and adding output statements and self-checking
-  code at critical places. Clicking over statements takes longer than
-  scanning the output of judiciously-placed displays. It takes less
-  time to decide where to put print statements than to single-step to
-  the critical section of code, even assuming we know where that
-  is. More important, debugging statements stay with the program;
-  debugging sessions are transient.
-
- -

Logging does have its drawbacks. It can slow down an -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, -the log4j API strives to be simple to understand and to use. - -

Loggers, Appenders and Layouts

- -

Log4j has three main components: loggers, -appenders and layouts. These three types of -components work together to enable developers to log messages according -to message type and level, and to control at runtime how these -messages are formatted and where they are reported. - -

Logger hierarchy

- -

The first and foremost advantage of any logging API over plain -System.out.println resides in its ability to disable -certain log statements while allowing others to print unhindered. This -capability assumes that the logging space, that is, the space of all -possible logging statements, is categorized according to some -developer-chosen criteria. This observation had previously led us to -choose category as the central concept of the -package. However, since log4j version 1.2, Logger class -has replaced the Category class. For those familiar with -earlier versions of log4j, the Logger class can be -considered as a mere alias to the Category class. - -

Loggers are named entities. Logger names are case-sensitive and -they follow the hierarchical naming rule: - -

- - -
-
-
Named Hierarchy - -

A logger is said to be an ancestor of another - logger if its name followed by a dot is a prefix of the - descendant logger name. A logger is said to be a - parent of a child logger if there are no - ancestors between itself and the descendant logger. - - -

-
- - -

For example, the logger named "com.foo" is a parent -of the logger named "com.foo.Bar". Similarly, -"java" is a parent of "java.util" and an -ancestor of "java.util.Vector". This naming scheme -should be familiar to most developers. - -

The root logger resides at the top of the logger hierarchy. It -is exceptional in two ways: - -

    -
  1. it always exists, -
  2. it cannot be retrieved by name. -
-

Invoking the class static Logger.getRootLogger -method retrieves it. All other loggers are instantiated and -retrieved with the class static Logger.getLogger -method. This method takes the name of the desired logger as a -parameter. Some of the basic methods in the Logger class are listed -below. - -

- - -
-
-  package org.apache.log4j;
-
-  public class Logger {
-
-    // Creation & retrieval methods:
-    public static Logger getRootLogger();
-    public static Logger getLogger(String name);
-
-    // printing methods:
-    public void trace(Object message);
-    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);
-}
-
-
- -

Loggers may be assigned levels. The set of possible -levels, that is - -TRACE, -DEBUG, -INFO, -WARN, -ERROR and -FATAL - -are defined in the org.apache.log4j.Level -class. Although we do not encourage you to do so, you may define -your own levels by sub-classing the Level class. A -perhaps better approach will be explained later on. - -

If a given logger is not assigned a level, then it inherits -one from its closest ancestor with an assigned level. More -formally: - - -

- - -
-
-
Level Inheritance - -

The inherited level for a given logger -C, is equal to the first non-null level in the logger -hierarchy, starting at C and proceeding upwards in the -hierarchy towards the root logger. - -

-
- -

To ensure that all loggers can eventually inherit a level, -the root logger always has an assigned level. - -

Below are four tables with various assigned level values and the -resulting inherited levels according to the above rule. - -

- - - - - - - - -
Logger
name
Assigned
level
Inherited
level
root Proot Proot
X none Proot
X.Y none Proot
X.Y.Z none Proot
Example 1
- -

In example 1 above, only the root logger is assigned a -level. This level value, Proot, is inherited by the -other loggers X, X.Y and -X.Y.Z. - - -

- - - - - - - - -
Logger
name
Assigned
level
Inherited
level
root Proot Proot
X Px Px
X.Y Pxy Pxy
X.Y.Z Pxyz Pxyz
Example 2
- -

In example 2, all loggers have an assigned level value. There -is no need for level inheritence. - -

- - - - - - - -
Logger
name
Assigned
level
Inherited
level
root Proot Proot
X Px Px
X.Y none Px
X.Y.Z Pxyz Pxyz
Example 3
- -

In example 3, the loggers root, X and -X.Y.Z are assigned the levels Proot, -Px and Pxyz respectively. The logger -X.Y inherits its level value from its parent -X. - - - - - - - - - -
Logger
name
Assigned
level
Inherited
level
root Proot Proot
X Px Px
X.Y none Px
X.Y.Z none Px
Example 4
- -

In example 4, the loggers root and X -and are assigned the levels Proot and Px -respectively. The loggers X.Y and X.Y.Z -inherits their level value from their nearest parent X -having an assigned level.. - - -

Logging requests are made by invoking one of the printing methods -of a logger instance. These printing methods are - - -debug, - -info, - -warn, -error, -fatal - and log. - - -

By definition, the printing method determines the level of a -logging request. For example, if c is a logger -instance, then the statement c.info("..") is a logging -request of level INFO. - -

A logging request is said to be enabled if its level is -higher than or equal to the level of its logger. Otherwise, the -request is said to be disabled. A logger without an -assigned level will inherit one from the hierarchy. This rule is -summarized below. - - -

- - -
-
-
Basic Selection Rule - -

A log request of level p in a logger with - (either assigned or inherited, whichever is appropriate) level q, is enabled if p >= - q. -

-
- -

This rule is at the heart of log4j. It assumes that levels are -ordered. For the standard levels, we have DEBUG < INFO -< WARN < ERROR < FATAL. - -

Here is an example of this rule. - -

-
-
-
-   // get a logger instance named "com.foo"
-   Logger  logger = Logger.getLogger("com.foo");
-
-   // Now set its level. Normally you do not need to set the
-   // level of a logger programmatically. This is usually done
-   // in configuration files.
-   logger.setLevel(Level.INFO);
-
-   Logger barlogger = Logger.getLogger("com.foo.Bar");
-
-   // This request is enabled, because WARN >= INFO.
-   logger.warn("Low fuel level.");
-
-   // This request is disabled, because DEBUG < INFO.
-   logger.debug("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 INFO >= INFO.
-   barlogger.info("Located nearest gas station.");
-
-   // This request is disabled, because DEBUG < INFO.
-   barlogger.debug("Exiting gas station search");
-
-
- -

Calling the getLogger method with the same name will -always return a reference to the exact same logger object. - -

For example, in - - - -
-
-   Logger x = Logger.getLogger("wombat");
-   Logger y = Logger.getLogger("wombat");
-
-x and y refer to exactly the same -logger object. - -

Thus, it is possible to configure a logger and then to retrieve -the same instance somewhere else in the code without passing around -references. In fundamental contradiction to biological parenthood, -where parents always preceed their children, log4j loggers can be -created and configured in any order. In particular, a "parent" -logger will find and link to its descendants even if it is -instantiated after them. - -

Configuration of the log4j environment is typically done at -application initialization. The preferred way is by reading a -configuration file. This approach will be discussed shortly. - -

Log4j makes it easy to name loggers by software -component. This can be accomplished by statically instantiating -a logger in each class, with the logger name equal to the fully -qualified name of the class. This is a useful and straightforward -method of defining loggers. As the log output bears the name of the -generating logger, this naming strategy makes it easy to identify -the origin of a log message. However, this is only one possible, -albeit common, strategy for naming loggers. Log4j does not restrict -the possible set of loggers. The developer is free to name the -loggers as desired. - -

Nevertheless, naming loggers after the class where they are -located seems to be the best strategy known so far. - -

Appenders and Layouts

- -

The ability to selectively enable or disable logging requests based -on their logger is only part of the picture. Log4j allows logging -requests to print to multiple destinations. In log4j speak, an output -destination is called an appender. Currently, appenders exist -for the console, files, GUI -components, remote socket -servers, JMS, - - NT -Event Loggers, and remote UNIX Syslog -daemons. It is also possible to log asynchronously. - -

More than one appender can be attached to a logger. - -

The addAppender -method adds an appender to a given logger. - -Each enabled logging -request for a given logger will be forwarded to all the appenders in -that logger as well as the appenders higher in the hierarchy. In -other words, appenders are inherited additively from the logger -hierarchy. For example, if a console appender is added to the root -logger, then all enabled logging requests will at least print on the -console. If in addition a file appender is added to a logger, say -C, then enabled logging requests for C and -C's children will print on a file and on the -console. It is possible to override this default behavior so that -appender accumulation is no longer additive by setting -the additivity flag to false. - -

The rules governing appender additivity are summarized below. - -

- - -
-
-
Appender Additivity - -

The output of a log statement of logger C will - go to all the appenders in C and its ancestors. This is - the meaning of the term "appender additivity". - -

However, if an ancestor of logger C, say P, - has the additivity flag set to false, then - C's output will be directed to all the appenders in - C and it's ancestors upto and including P but - not the appenders in any of the ancestors of P. - -

Loggers have their additivity flag set to - true by default. -

-
- - -

The table below shows an example: - -

- -
Logger
Name
Added
Appenders
Additivity
Flag
Output Targets Comment - -
root A1 not applicable A1 - - The root logger is anonymous but can be accessed with the - Logger.getRootLogger() method. There is no default appender - attached to root. - -
x A-x1, A-x2 true A1, A-x1, A-x2 - Appenders of "x" and root. - -
x.y none true A1, A-x1, A-x2 - Appenders of "x" and root. - -
x.y.z A-xyz1 true A1, A-x1, A-x2, A-xyz1 - Appenders in "x.y.z", "x" and root. - -
security A-sec false - A-sec - - No appender accumulation since the additivity flag is set to - false. - -
security.access none true A-sec Only - appenders of "security" because the additivity flag in "security" is - set to false. - -
- - -

More often than not, users wish to customize not only the output -destination but also the output format. This is accomplished by -associating a layout 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. - -The PatternLayout, part -of the standard log4j distribution, lets the user specify the output -format according to conversion patterns similar to the C language -printf function. - -

For example, the PatternLayout with the conversion pattern "%r [%t] -%-5p %c - %m%n" will output something akin to: - -

-176 [main] INFO  org.foo.Bar - Located nearest gas station.
-
- -

The first field is the number of milliseconds elapsed since the -start of the program. The second field is the thread making the log -request. The third field is the level of the log statement. The -fourth field is the name of the logger associated with the log -request. The text after the '-' is the message of the statement. - -

Just as importantly, log4j will render the content of the log -message according to user specified criteria. For example, if you -frequently need to log Oranges, an object type used in -your current project, then you can register an -OrangeRenderer that will be invoked whenever an orange -needs to be logged. - -

Object rendering follows the class hierarchy. For example, assuming -oranges are fruits, if you register an FruitRenderer, all -fruits including oranges will be rendered by the -FruitRenderer, unless of course you registered an orange -specific OrangeRenderer. - -

Object renderers have to implement the -ObjectRenderer -interface. - - -

Configuration

- -

Inserting log requests into the application code requires a fair -amount of planning and effort. Observation shows that approximately 4 -percent of code is dedicated to logging. Consequently, even moderately -sized applications will have thousands of logging statements embedded -within their code. Given their number, it becomes imperative to -manage these log statements without the need to modify them manually. - -

The log4j environment is fully configurable programmatically. -However, it is far more flexible to configure log4j using -configuration files. Currently, configuration files can be written in -XML or in Java properties (key=value) format. - -

Let us give a taste of how this is done with the help of an -imaginary application MyApp that uses log4j. - -

-
- import com.foo.Bar;
-
- // Import log4j classes.
- import org.apache.log4j.Logger;
- import org.apache.log4j.BasicConfigurator;
-
- public class MyApp {
-
-   // Define a static logger variable so that it references the
-   // Logger instance named "MyApp".
-   static Logger logger = Logger.getLogger(MyApp.class);
-
-   public static void main(String[] args) {
-
-     // Set up a simple configuration that logs on the console.
-     BasicConfigurator.configure();
-
-     logger.info("Entering application.");
-     Bar bar = new Bar();
-     bar.doIt();
-     logger.info("Exiting application.");
-   }
- }
-
-
- -

MyApp begins by importing log4j related classes. It -then defines a static logger variable with the name -MyApp which happens to be the fully qualified name of the -class. - -

MyApp uses the Bar class defined in the -package com.foo. - -

-
- package com.foo;
- import org.apache.log4j.Logger;
-
- public class Bar {
-   static Logger logger = Logger.getLogger(Bar.class);
-
-   public void doIt() {
-     logger.debug("Did it again!");
-   }
- }
-
-
- -

The invocation of the BasicConfigurator.configure -method creates a rather simple log4j setup. This method is hardwired -to add to the root logger a -ConsoleAppender. The output will be formatted using a PatternLayout set -to the pattern "%-4r [%t] %-5p %c %x - %m%n". - -

Note that by default, the root logger is assigned to -Level.DEBUG. - -

The output of MyApp is: -

-0    [main] INFO  MyApp  - Entering application.
-36   [main] DEBUG com.foo.Bar  - Did it again!
-51   [main] INFO  MyApp  - Exiting application.
-
- -

The figure below depicts the object diagram of MyApp -after just having called the BasicConfigurator.configure -method. - -

-

- -
- -

As a side note, let me mention that in log4j child loggers link -only to their existing ancestors. In particular, the logger named -com.foo.Bar is linked directly to the root -logger, thereby circumventing the unused com or -com.foo loggers. This significantly increases -performance and reduces log4j's memory footprint. - - -

The MyApp class configures log4j by invoking -BasicConfigurator.configure method. Other classes only -need to import the org.apache.log4j.Logger class, -retrieve the loggers they wish to use, and log away. - -

The previous example always outputs the same log information. -Fortunately, it is easy to modify MyApp so that the log -output can be controlled at run-time. Here is a slightly modified -version. - -

-
- import com.foo.Bar;
-
- import org.apache.log4j.Logger;
- import org.apache.log4j.PropertyConfigurator;
-
- public class MyApp {
-
-   static Logger logger = Logger.getLogger(MyApp.class.getName());
-
-   public static void main(String[] args) {
-
-
-     // BasicConfigurator replaced with PropertyConfigurator.
-     PropertyConfigurator.configure(args[0]);
-
-     logger.info("Entering application.");
-     Bar bar = new Bar();
-     bar.doIt();
-     logger.info("Exiting application.");
-   }
- }
-
-
- -

This version of MyApp instructs -PropertyConfigurator to parse a configuration file and -set up logging accordingly. - -

Here is a sample configuration file that results in exactly same -output as the previous BasicConfigurator based example. - -

-
-# Set root logger level to DEBUG and its only appender to A1.
-log4j.rootLogger=DEBUG, A1
-
-# 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
-
-
- - -

Suppose we are no longer interested in seeing the output of any -component belonging to the com.foo package. The following -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
-
-# Print the date in ISO 8601 format
-log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
-
-# Print only messages of level WARN or above in the package com.foo.
-log4j.logger.com.foo=WARN
-
-
- -

The output of MyApp configured with this file is shown below. - -

-2000-09-07 14:07:41,508 [main] INFO  MyApp - Entering application.
-2000-09-07 14:07:41,529 [main] INFO  MyApp - Exiting application.
-
- -

As the logger com.foo.Bar does not have an assigned -level, it inherits its level from com.foo, which -was set to WARN in the configuration file. The log statement from the -Bar.doIt method has the level DEBUG, lower than the -logger level WARN. Consequently, doIt() method's log -request is suppressed. - -

Here is another configuration file that uses multiple appenders. - -

-
-log4j.rootLogger=debug, stdout, R
-
-log4j.appender.stdout=org.apache.log4j.ConsoleAppender
-log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-
-# Pattern to output the caller's file name and line number.
-log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
-
-log4j.appender.R=org.apache.log4j.RollingFileAppender
-log4j.appender.R.File=example.log
-
-log4j.appender.R.MaxFileSize=100KB
-# Keep one backup file
-log4j.appender.R.MaxBackupIndex=1
-
-log4j.appender.R.layout=org.apache.log4j.PatternLayout
-log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
-
-
- -

Calling the enhanced MyApp with the this configuration file will -output the following on the console. - -

- INFO [main] (MyApp2.java:12) - Entering application.
-DEBUG [main] (Bar.java:8) - Doing it again!
- INFO [main] (MyApp2.java:15) - Exiting application.
-
- -

In addition, as the root logger has been allocated a second -appender, output will also be directed to the example.log -file. This file will be rolled over when it reaches 100KB. When -roll-over occurs, the old version of example.log is -automatically moved to example.log.1. - -

Note that to obtain these different logging behaviors we did not -need to recompile code. We could just as easily have logged to a UNIX -Syslog daemon, redirected all com.foo output to an NT -Event logger, or forwarded logging events to a remote log4j server, -which would log according to local server policy, for example by -forwarding the log event to a second log4j server. - -

Default Initialization Procedure

- -

The log4j library does not make any assumptions about its -environment. In particular, there are no default log4j -appenders. Under certain well-defined circumstances however, the -static inializer of the Logger class will attempt to -automatically configure log4j. The Java language guarantees that the -static initializer of a class is called once and only once during the -loading of a class into memory. It is important to remember that -different classloaders may load distinct copies of the same -class. These copies of the same class are considered as totally -unrelated by the JVM. - -

The default initialization is very useful in environments where the -exact entry point to the application depends on the runtime -environment. For example, the same application can be used as a -stand-alone application, as an applet, or as a servlet under the -control of a web-server. - -

The exact default initialization algorithm is defined as follows: - -

    - -
  1. Setting the log4j.defaultInitOverride system property to - any other value then "false" will cause log4j to skip the default - initialization procedure (this procedure). - -

  2. Set the resource string variable to the value of - the log4j.configuration system property. The preferred - way to specify the default initialization file is through the - log4j.configuration system property. In case the system - property log4j.configuration is not defined, then set the - string variable resource to its default value - "log4j.properties". - -

  3. Attempt to convert the resource variable to a - URL. - -

  4. If the resource variable cannot be converted to a URL, for - example due to a MalformedURLException, then search for - the resource from the classpath by calling - org.apache.log4j.helpers.Loader.getResource(resource, - Logger.class) which returns a URL. Note that the string - "log4j.properties" constitutes a malformed URL. - -

    See Loader.getResource(java.lang.String) - for the list of searched locations. - -

  5. If no URL could not be found, abort default - initialization. Otherwise, configure log4j from the URL. - -

    The PropertyConfigurator - will be used to parse the URL to configure log4j unless the URL ends - with the ".xml" extension, in which case the DOMConfigurator - will be used. You can optionaly specify a custom configurator. The - value of the log4j.configuratorClass system property is taken - as the fully qualified class name of your custom configurator. The - custom configurator you specify must implement the Configurator - interface. - -

- -

Example Configurations

- - - -

Default Initialization under Tomcat

- -

The default log4j initialization is particularly useful in -web-server environments. Under Tomcat 3.x and 4.x, you should place -the log4j.properties under the -WEB-INF/classes directory of your web-applications. Log4j -will find the properties file and initialize itself. This is easy to -do and it works. - -

You can also choose to set the system property -log4j.configuration before starting Tomcat. For Tomcat 3.x The -TOMCAT_OPTS environment variable is used to set command -line options. For Tomcat 4.0, set the CATALINA_OPTS -environment variable instead of TOMCAT_OPTS. - -

Example 1 - -

The Unix shell command -

-   export TOMCAT_OPTS="-Dlog4j.configuration=foobar.txt"
-
- -tells log4j to use the file foobar.txt as the default -configuration file. This file should be place under the -WEB-INF/classes directory of your web-application. The -file will be read using the PropertyConfigurator. Each -web-application will use a different default configuration file because -each file is relative to a web-application. - - -

Example 2 - -

The Unix shell command -

-   export TOMCAT_OPTS="-Dlog4j.debug -Dlog4j.configuration=foobar.xml"
-
- -tells log4j to output log4j-internal debugging information and to use -the file foobar.xml as the default configuration -file. This file should be place under the WEB-INF/classes -directory of your web-application. Since the file ends with a -.xml extension, it will read using the DOMConfigurator. Each -web-application will use a different default configuration file because -each file is relative to a web-application. - -

Example 3 - -

The Windows shell command -

-   set TOMCAT_OPTS=-Dlog4j.configuration=foobar.lcf -Dlog4j.configuratorClass=com.foo.BarConfigurator
-
- -tells log4j to use the file foobar.lcf as the default -configuration file. This file should be place under the -WEB-INF/classes directory of your web-application. Due to -the definition of the log4j.configuratorClass system property, -the file will be read using the com.foo.BarConfigurator -custom configurator. Each web-application will use a different -default configuration file because each file is relative to a -web-application. - -

Example 4 - -

The Windows shell command -

-   set TOMCAT_OPTS=-Dlog4j.configuration=file:/c:/foobar.lcf
- -tells log4j to use the file c:\foobar.lcf as the default -configuration file. The configuration file is fully specified by the -URL file:/c:/foobar.lcf. Thus, the same configuration -file will be used for all web-applications. - - -

Different web-applications will load the log4j classes through -their respective classloaderss. Thus, each image of the log4j -environment will act independetly and without any mutual -synchronization. For example, FileAppenders defined -exactly the same way in multiple web-application configurations will -all attempt to write the same file. The results are likely to be less -than satisfactory. You must make sure that log4j configurations of -different web-applications do not use the same underlying system -resource. - - -

Initialization servlet - -

It is also possible to use a special servlet for log4j -initialization. Here is an example, - -

-
-package com.foo;
-
-import org.apache.log4j.PropertyConfigurator;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.PrintWriter;
-import java.io.IOException;
-
-public class Log4jInit extends HttpServlet {
-
-  public
-  void init() {
-    String prefix =  getServletContext().getRealPath("/");
-    String file = getInitParameter("log4j-init-file");
-    // if the log4j-init-file is not set, then no point in trying
-    if(file != null) {
-      PropertyConfigurator.configure(prefix+file);
-    }
-  }
-
-  public
-  void doGet(HttpServletRequest req, HttpServletResponse res) {
-  }
-}
-
-
- -

Define the following servlet in the web.xml file for your web-application. - -

-
-  <servlet>
-    <servlet-name>log4j-init</servlet-name>
-    <servlet-class>com.foo.Log4jInit</servlet-class>
-
-    <init-param>
-      <param-name>log4j-init-file</param-name>
-      <param-value>WEB-INF/classes/log4j.lcf</param-value>
-    </init-param>
-
-    <load-on-startup>1</load-on-startup>
-  </servlet>
-
-
- -

Writing an initialization servlet is the most flexible way for -initializing log4j. There are no constraints on the code you can place -in the init() method of the servlet. - - - -

Nested Diagnostic Contexts

- -

Most real-world systems have to deal with multiple clients -simultaneously. In a typical multithreaded implementation of such a -system, different threads will handle different clients. Logging is -especially well suited to trace and debug complex distributed -applications. A common approach to differentiate the logging output of -one client from another is to instantiate a new separate logger for -each client. This promotes the proliferation of loggers and -increases the management overhead of logging. - -

A lighter technique is to uniquely stamp each log request initiated -from the same client interaction. Neil Harrison described this method -in the book "Patterns for Logging Diagnostic Messages," in Pattern -Languages of Program Design 3, edited by R. Martin, D. Riehle, -and F. Buschmann (Addison-Wesley, 1997). - - - -

To uniquely stamp each request, the -user pushes contextual information into the NDC, the abbreviation of -Nested Diagnostic Context. The NDC class is shown below. - -

-  public class NDC {
-    // Used when printing the diagnostic
-    public static String get();
-
-    // Remove the top of the context from the NDC.
-    public static String pop();
-
-    // Add diagnostic context for the current thread.
-    public static void push(String message);
-
-    // Remove the diagnostic context for this thread.
-    public static void remove();
-  }
-
- -

The NDC is managed per thread as a stack of contextual -information. Note that all methods of the org.apache.log4j.NDC -class are static. Assuming that NDC printing is turned on, every time -a log request is made, the appropriate log4j component will include -the entire NDC stack for the current thread in the log -output. This is done without the intervention of the user, who is -responsible only for placing the correct information in the NDC by -using the push and pop methods at a few -well-defined points in the code. In contrast, the per-client logger -approach commands extensive changes in the code. - -

To illustrate this point, let us take the example of a servlet -delivering content to numerous clients. The servlet can build the NDC -at the very beginning of the request before executing other code. The -contextual information can be the client's host name and other -information inherent to the request, typically information contained -in cookies. Hence, even if the servlet is serving multiple clients -simultaneously, the logs initiated by the same code, i.e. belonging to -the same logger, can still be distinguished because each client -request will have a different NDC stack. Contrast this with the -complexity of passing a freshly instantiated logger to all code -exercised during the client's request. - -

Nevertheless, some sophisticated applications, such as virtual -hosting web servers, must log differently depending on the virtual -host context and also depending on the software component issuing the -request. Recent log4j releases support multiple hierarchy trees. This -enhancement allows each virtual host to possess its own copy of the -logger hierarchy. - - -

Performance

- -

One of the often-cited arguments against logging is its -computational cost. This is a legitimate concern as even moderately -sized applications can generate thousands of log requests. Much -effort was spent measuring and tweaking logging performance. Log4j -claims to be fast and flexible: speed first, flexibility second. - -

The user should be aware of the following performance issues. - -

    -
  1. Logging performance when logging is turned off. - -

    When logging is turned - off entirely or just for a set - of levels, the cost of a log request consists of a method - invocation plus an integer comparison. On a 233 MHz Pentium II - machine this cost is typically in the 5 to 50 nanosecond range. - -

    However, The method invocation involves the "hidden" cost of - parameter construction. - -

    For example, for some logger cat, writing, -

    -     logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
    -    
    - - incurs the cost of constructing the message parameter, i.e. - converting both integer i and entry[i] - to a String, and concatenating intermediate strings, - regardless of whether the message will be logged or not. - - This cost of parameter construction can be quite high and it - depends on the size of the parameters involved. - - -

    To avoid the parameter construction cost write: -

    -      if(logger.isDebugEnabled() {
    -        logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
    -      }
    -   
    - -

    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 - evaluating whether the logger is enabled or not: once - in debugEnabled and once in - debug. This is an insignificant - overhead because evaluating a logger takes about 1% - of the time it takes to actually log. - -

    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 - flexibility. - - -

    Certain users resort to preprocessing or compile-time - techniques to compile out all log statements. This leads to perfect - performance efficiency with respect to logging. However, since the - resulting application binary does not contain any log statements, - logging cannot be turned on for that binary. In my opinion this is - a disproportionate price to pay in exchange for a small performance - gain. - - -

  2. The performance of deciding whether to log or not to log when - logging is turned on. -

    - -

    This is essentially the performance of walking the logger - hierarchy. When logging is turned on, log4j still needs to compare - the level of the log request with the level of the request - logger. However, loggers may not have an assigned - level; they can inherit them from the logger hierarchy. Thus, - before inheriting a level, the logger may need to search its - ancestors. - -

    There has been a serious effort to make this hierarchy walk to -be as fast as possible. For example, child loggers link only to -their existing ancestors. In the BasicConfigurator -example shown earlier, the logger named com.foo.Bar is -linked directly to the root logger, thereby circumventing the -nonexistent com or com.foo loggers. This -significantly improves the speed of the walk, especially in "sparse" -hierarchies. - -

    The typical cost of walking the hierarchy is typically 3 - times slower than when logging is turned off entirely. - -

  3. Actually outputting log messages - -

    This is the cost of formatting the log output and sending it to - its target destination. Here again, a serious effort was made to - make layouts (formatters) perform as quickly as possible. The same - is true for appenders. The typical cost of actually logging is - about 100 to 300 microseconds. - - See org.apache.log4.performance.Logging - for actual figures. - -

- -

Although log4j has many features, its first design goal was speed. -Some log4j components have been rewritten many times to improve -performance. Nevertheless, contributors frequently come up with new -optimizations. You should be pleased to know that when configured with -the SimpleLayout -performance tests have shown log4j to log as quickly as -System.out.println. - -

Conclusions

- -

Log4j is a popular logging package written in Java. One of its -distinctive features is the notion of inheritance in loggers. Using -a logger hierarchy it is possible to control which log statements -are output at arbitrary granularity. This helps reduce the volume of -logged output and minimize the cost of logging. - -

One of the advantages of the log4j API is its manageability. Once -the log statements have been inserted into the code, they can be -controlled with configuration files. They can be selectively enabled -or disabled, and sent to different and multiple output targets in -user-chosen formats. The log4j package is designed so that log -statements can remain in shipped code without incurring a heavy -performance cost. - -

Acknowledgments

- -Many thanks to N. Asokan for reviewing the article. He is also one of -the originators of the logger concept. I am indebted to Nelson Minar -for encouraging me to write this article. He has also made many useful -suggestions and corrections to this article. Log4j is the result of a -collective effort. My special thanks go to all the authors who have -contributed to the project. Without exception, the best features in -the package have all originated in the user community. - - diff --git a/docs/overview.html b/docs/overview.html deleted file mode 100644 index 35f20e96e3..0000000000 --- a/docs/overview.html +++ /dev/null @@ -1,12 +0,0 @@ - - - -Short log4j introduction - - -The reliable, fast and flexible logging framework for Java. - -

Make sure to read the user manual -in addition to this javadoc documentation. - - diff --git a/docs/plan.html b/docs/plan.html deleted file mode 100644 index 0a23a1d6ba..0000000000 --- a/docs/plan.html +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Log4j project - Release roadmap for log4j - - - - - - - - - - - -

-
- -

The Roadmap

-

This page documents that roadmap and gives you an idea of what - to expect from future versions and timeframes for release. -

-

Our users keep inventing better ways and adding new - requirements. The downside is that our todo list keeps - growing. The upside is that there is plenty of work to go - around. If you are interested in participating, send an email - on the log4j-dev@ mailing list stating your interest. You'll - be promptly enrolled. We're always looking for help! Don't be - put off if in the "Volunteer" column already has a person - listed. Programming is fun, especially if it is done in a - team. -

-

Release 1.2.15

-

Expected timeframe: As needed

-

log4j 1.2.14 was released in September 2006. log4j 1.2 is continuing to be maintained - in response to reported, but no active development is anticipated in the near future. Backporting - the org.apache.log4j.rolling package from log4j 1.3 might be desirable since usage problems - with the original org.apache.log4j.RollingFileAppender and org.apache.log4j.DailyRollingFileAppender - are commonly reported.

-

Release 1.3

-

Expected timeframe: indeterminate

-

Compatibility with earlier releases (as implied by a minor verion number change) was not enforced during the - development process and much of the recent effort has been to restore compatibility. However, it does not - seem likely that log4j 1.3 will ever been sufficiently compatible with log4j 1.2 - to recommend it as a general replacement for log4j 1.2. Additional alpha releases are expected, - however it is possible that the development focus may shift to log4j 2.0.

-

Release 2.0

-

Expected timeframe: indeterminate

-

log4j 2.0 is still conceptual but would be designed for Java 5 and later, - would use be designed for fine-grain concurrency to maximize performance on - multi-processor systems, would minimize exposure of implementation details and - adhere to current Java coding practices. The design of log4j 2.0 may attempt to - support javax.util.logging by allowing, for example, a log4j 2.0 Appender to serve - as a javax.util.logging.Handler. log4j 2.0 would likely be modularized, possibly using - OSGi and would include a facade that emulates the log4j 1.3 API but would not be compatible - with user written appenders and other components.

- - - -
- - - - - - -
- Copyright © 1999-2006, Apache Software Foundation.
-Licensed under the Apache License, Version 2.0. -
- - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/praise.html b/docs/praise.html deleted file mode 100755 index e6d10d0e9b..0000000000 --- a/docs/praise.html +++ /dev/null @@ -1,266 +0,0 @@ - - -Praise from log4j users - - - -

Praise from log4j users

- -
-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. -
-

JavaWorld, April 2001 - -


-

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. - -

Highly configurable - 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). - -

Unobtrusive - 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. - -

Easy configuration - 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. - -

Performance Concerns - 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. - -

Hierarchical Categories - 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. - -

Easily specified output format - 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. - -

Customization - 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. -

- -

Paul Glezen (pglezen at atdial.net), December 3rd, 2000 - -


-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. -
- -

Denis Balazuc (denis.balazuc at trader.com), December 8th, 2000 - -


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. -
- -

Paul Hyndman (PaulHyndman at mynd.com), November 29th, 2000 - -


-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. -
- -

Rich Coco (racoco at celoxnetworks.com), November 16th, 2000 - - - -


- -Just thought I'd let you know that I am using your log4j as a part of -an e-commerce application (www.consumerd.com). I am using -the XML configuration classes and have to say that I am most -impressed. -
- -

Richard King (Richard.King at capgemini.co.uk), October 25th, 2000 - -


- -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. - -

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. - -

-

Christopher Taylor (cstaylor at pacbell.net), September 2nd, 2000 - -


-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. -
- -

Manish Balsara (manishb at aumsoft.com) August 28th, 2000 - -


-Thank you for writing this incredibly effective piece of software. You -have made my and my team's lives much easier. -
- -

Guy Nirpaz, Java Architect (guyn at tantian.com) August -14th, 2000 - -


-Thank you so much for developing such a -sleek package. I think it's going to be a part of many of my projects in -the future :) -
- -

Alice Nakajima (alice.t.nakajima at saic.com) May 10th, -2000 - - -


-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. -
- -

Zeng Qiang (zeng.qiang at europeloan.com) April 26th, 2000 - -


-
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. -

Jianbo Wang (jiwang at Daleen.com) April -25th, 2000 - -


-
-Was trying to use the log4j tracer ... great job, by the way ! - -

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. -

-

Joerg Palmer (Joerg.Palmer at Compart.net) April 14th, 2000 - - -


-
-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 presto, logging to a file. They're happy. -
-

Nelson Minar CTO, Popular Power, Inc. (nelson at popularpower.com) April 14th, 2000 - -


-
-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! :-) -
-

Anthony (ant at sanlam.co.za) April 13th, 2000 - - -


-
-Thanks for providing log4j: it's a very useful package. -
-

Andrew Harris (Andrew.Harris at capgemini.co.uk) April 10th, 2000 - -


-
-I just started using log4j v.0.8.1. It is quite what I was looking for. -

So here is my "THANK YOU" to all the contributors. -I think I'll join the club. -

-

Avy Sharell (asharell at club-internet.fr) March 8th, 2000 - - -


-
-I just wanted to thank you for log4j which is a great piece of software! - -

We are using it in the FREE e-democracy project -http://www.thecouch.org/free/ to provide an effective security audit -trail in our electronic voting software. -

-

Jason Kitcat (jeep at thecouch.org) March 29th, 2000 - - -


-
-Thanks for making log4j available. -I like the changes in v0.8 and am using it in all my java projects. -
-

Steven Marcus (srnm at awaretechnologies.com) February 19th, 2000 - -


-
-First congratulation for your great job on the Log mechanism log4j, -it's really valuable. -
-

Sebastien Sahuc (ssahuc at imediation.com) January 4th, 2000 - - -


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.

Jens Uwe Pipka (jens.pipka at gmx.de) October 25th, 1999 - -


- diff --git a/docs/ugli.html b/docs/ugli.html deleted file mode 100644 index 00cc412e40..0000000000 --- a/docs/ugli.html +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - Log4j project - Universal and Generic Logging Interface (UGLI) - - - - - - - - - - - -
-
- -

Universal and Generic Logging Interface (UGLI)

-

The Universal and Generic Logging Interface effort has been - renamed as SLF4J and moved to slf4j.org.

- - - -
- - - - - - -
- Copyright © 1999-2006, Apache Software Foundation.
-Licensed under the Apache License, Version 2.0. -
- - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/.cvsignore b/examples/.cvsignore deleted file mode 100644 index 2ac8d3d48b..0000000000 --- a/examples/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -doc-files -classes diff --git a/examples/MyPatternLayout.java b/examples/MyPatternLayout.java new file mode 100644 index 0000000000..8cb563da8e --- /dev/null +++ b/examples/MyPatternLayout.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package examples; + +import org.apache.log4j.*; +import org.apache.log4j.helpers.PatternParser; + +/** + + Example showing how to extend PatternLayout to recognize additional + conversion characters. + +

In this case MyPatternLayout recognizes %# conversion pattern. It + outputs the value of an internal counter which is also incremented + at each call. + +

See source code + for more details. + + @see MyPatternParser + @see org.apache.log4j.PatternLayout + @author Anders Kristensen +*/ +public class MyPatternLayout extends PatternLayout { + public + MyPatternLayout() { + this(DEFAULT_CONVERSION_PATTERN); + } + + public + MyPatternLayout(String pattern) { + super(pattern); + } + + public + PatternParser createPatternParser(String pattern) { + return new MyPatternParser( + pattern == null ? DEFAULT_CONVERSION_PATTERN : pattern); + } + + public + static void main(String[] args) { + Layout layout = new MyPatternLayout("[counter=%.10#] - %m%n"); + 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/MyPatternParser.java b/examples/MyPatternParser.java new file mode 100644 index 0000000000..b65746bec8 --- /dev/null +++ b/examples/MyPatternParser.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package examples; + +import org.apache.log4j.helpers.FormattingInfo; +import org.apache.log4j.helpers.PatternConverter; +import org.apache.log4j.helpers.PatternParser; +import org.apache.log4j.spi.LoggingEvent; + +/** + Example showing how to extend PatternParser to recognize additional + conversion characters. The examples shows that minimum and maximum + width and alignment settings apply for "extension" conversion + characters just as they do for PatternLayout recognized characters. + +

In this case MyPatternParser recognizes %# and outputs the value + of an internal counter which is also incremented at each call. + + See source code + for more details. + + @see org.apache.log4j.examples.MyPatternLayout + @see org.apache.log4j.helpers.PatternParser + @see org.apache.log4j.PatternLayout + + @author Anders Kristensen +*/ +public class MyPatternParser extends PatternParser { + + int counter = 0; + + public + MyPatternParser(String pattern) { + super(pattern); + } + + public + void finalizeConverter(char c) { + if (c == '#') { + addConverter(new UserDirPatternConverter(formattingInfo)); + currentLiteral.setLength(0); + } else { + super.finalizeConverter(c); + } + } + + private class UserDirPatternConverter extends PatternConverter { + UserDirPatternConverter(FormattingInfo formattingInfo) { + super(formattingInfo); + } + + public + String convert(LoggingEvent event) { + return String.valueOf(++counter); + } + } +} diff --git a/examples/NumberCruncher.java b/examples/NumberCruncher.java new file mode 100644 index 0000000000..84ba303c28 --- /dev/null +++ b/examples/NumberCruncher.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package examples; + +import java.rmi.Remote; +import java.rmi.RemoteException; + +/** + NumberCruncher's factor positive integers. See source code for more details. + + @author Ceki Gülcü + +*/ +public interface NumberCruncher extends Remote { + + /** + Factor a positive integer number and return its + distinct factor's as an integer array. + */ + int[] factor(int number) throws RemoteException; +} diff --git a/examples/src/factor/NumberCruncherClient.java b/examples/NumberCruncherClient.java similarity index 86% rename from examples/src/factor/NumberCruncherClient.java rename to examples/NumberCruncherClient.java index 24a7b18a89..4f58271bc4 100644 --- a/examples/src/factor/NumberCruncherClient.java +++ b/examples/NumberCruncherClient.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -14,7 +15,7 @@ * limitations under the License. */ -package factor; +package examples; import java.rmi.RemoteException; import java.rmi.Naming; diff --git a/examples/NumberCruncherServer.java b/examples/NumberCruncherServer.java new file mode 100644 index 0000000000..e981243d64 --- /dev/null +++ b/examples/NumberCruncherServer.java @@ -0,0 +1,172 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package examples; + +import java.rmi.server.UnicastRemoteObject; +import java.rmi.RemoteException; +import java.rmi.Naming; +import java.util.Vector; + +import org.apache.log4j.Logger; +import org.apache.log4j.NDC; +import org.apache.log4j.PropertyConfigurator; + +/** + A simple {@link NumberCruncher} implementation that logs its + progress when factoring numbers. The purpose of the whole exercise + is to show the use of nested diagnostic contexts in order to + distinguish the log output from different client requests. + +

+   Usage: java org.apache.log4j.examples.NumberCruncherServer configFile
+          where configFile is a log4j configuration file.
+   
+ + We supply a simple config file factor.lcf + for directing log output to the file factor.log. + +

Try it yourself by starting a NumberCruncherServer + and make queries from multiple {@link NumberCruncherClient + NumberCruncherClients} to factor numbers. + + +

Sample output shows the log + output when two clients connect to the server near simultaneously. + +

See source code + of NumberCruncherServer for more details. + +

Note that class files for the example code is not included in + any of the distributed log4j jar files. You will have to add the + directory /dir-where-you-unpacked-log4j/classes to + your classpath before trying out the examples. + + + */ +public class NumberCruncherServer extends UnicastRemoteObject + implements NumberCruncher { + private static final long serialVersionUID = 2626753561969426769L; + + + static Logger logger = Logger.getLogger(NumberCruncherServer.class); + + public + NumberCruncherServer() throws RemoteException { + } + + public + int[] factor(int number) throws RemoteException { + + // The client's host is an important source of information. + try { + NDC.push(getClientHost()); + } + catch(java.rmi.server.ServerNotActiveException e) { + // we are being called from same VM + NDC.push("localhost"); + } + + // The information contained within the request is another source of + // distinctive information. It might reveal the users name, date of request, + // request ID etc. In servlet type environments, much information is + // contained in cookies. + NDC.push(String.valueOf(number)); + + logger.info("Beginning to factor."); + if(number <= 0) { + throw new IllegalArgumentException(number+" is not a positive integer."); + } + else if(number == 1) + return new int[] {1}; + + Vector factors = new Vector(); + int n = number; + + for(int i = 2; (i <= n) && (i*i <= number); i++) { + // It is bad practice to place log requests within tight loops. + // It is done here to show interleaved log output from + // different requests. + logger.debug("Trying to see if " + i + " is a factor."); + + if((n % i) == 0) { + logger.info("Found factor "+i); + factors.addElement(new Integer(i)); + do { + n /= i; + } while((n % i) == 0); + } + // Placing artificial delays in tight-loops will also lead to sub-optimal + // resuts. :-) + delay(100); + } + + if(n != 1) { + logger.info("Found factor "+n); + factors.addElement(new Integer(n)); + } + + int len = factors.size(); + + int[] result = new int[len]; + for(int i = 0; i < len; i++) { + result[i] = ((Integer) factors.elementAt(i)).intValue(); + } + + // Before leaving a thread we call NDC.remove. This deletes the reference + // to the thread in the internal hash table. Version 0.8.5 introduces a + // a lazy removal mechanism in case you forget to call remove when + // exiting a thread. See the java documentation in NDC.remove for further + // details. + NDC.remove(); + + return result; + } + + static + void usage(String msg) { + System.err.println(msg); + System.err.println( + "Usage: java org.apache.log4j.examples.NumberCruncherServer configFile\n" + + " where configFile is a log4j configuration file."); + System.exit(1); + } + + public static + void delay(int millis) { + try{Thread.sleep(millis);} + catch(InterruptedException e) {} + } + + public static void main(String[] args) { + if(args.length != 1) + usage("Wrong number of arguments."); + + NumberCruncherServer ncs; + PropertyConfigurator.configure(args[0]); + try { + ncs = new NumberCruncherServer(); + Naming.rebind("Factor", ncs); + logger.info("NumberCruncherServer bound and ready to serve."); + } + catch(Exception e) { + logger.error("Could not bind NumberCruncherServer.", e); + return; + } + NumberCruncherClient.loop(ncs); + } +} diff --git a/examples/Sort.java b/examples/Sort.java new file mode 100644 index 0000000000..7b97225058 --- /dev/null +++ b/examples/Sort.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package examples; + +import org.apache.log4j.PropertyConfigurator; +import org.apache.log4j.Logger; + +/** + Example code for log4j to viewed in conjunction with the {@link + examples.SortAlgo SortAlgo} class. + +

This program expects a configuration file name as its first + argument, and the size of the array to sort as the second and last + argument. See its source + code for more details. + +

Play around with different values in the configuration file and + watch the changing behavior. + +

Example configuration files can be found in sort1.properties, sort2.properties, sort3.properties and sort4.properties are supplied with the + package. + +

If you are also interested in logging performance, then have + look at the {@link org.apache.log4j.performance.Logging} class. + + @author Ceki Gülcü */ + +public class Sort { + + static Logger logger = Logger.getLogger(Sort.class.getName()); + + public static void main(String[] args) { + if(args.length != 2) { + usage("Incorrect number of parameters."); + } + int arraySize = -1; + try { + arraySize = Integer.valueOf(args[1]).intValue(); + if(arraySize <= 0) + usage("Negative array size."); + } + catch(java.lang.NumberFormatException e) { + usage("Could not number format ["+args[1]+"]."); + } + + PropertyConfigurator.configure(args[0]); + + int[] intArray = new int[arraySize]; + + logger.info("Populating an array of " + arraySize + " elements in" + + " reverse order."); + for(int i = arraySize -1 ; i >= 0; i--) { + intArray[i] = arraySize - i - 1; + } + + SortAlgo sa1 = new SortAlgo(intArray); + sa1.bubbleSort(); + sa1.dump(); + + // We intentionally initilize sa2 with null. + SortAlgo sa2 = new SortAlgo(null); + logger.info("The next log statement should be an error message."); + sa2.dump(); + logger.info("Exiting main method."); + } + + static + void usage(String errMsg) { + System.err.println(errMsg); + System.err.println("\nUsage: java org.apache.examples.Sort " + + "configFile ARRAY_SIZE\n"+ + "where configFile is a configuration file\n"+ + " ARRAY_SIZE is a positive integer.\n"); + System.exit(1); + } +} diff --git a/examples/SortAlgo.java b/examples/SortAlgo.java new file mode 100644 index 0000000000..dde9ce811c --- /dev/null +++ b/examples/SortAlgo.java @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package examples; + +import org.apache.log4j.Logger; +import org.apache.log4j.NDC; + +/** + Example code for log4j to viewed in conjunction with the {@link + examples.Sort Sort} class. + +

SortAlgo uses the bubble sort algorithm to sort an integer + array. See also its source + code. + + @author Ceki Gülcü */ +public class SortAlgo { + + final static String className = SortAlgo.class.getName(); + 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; + + SortAlgo(int[] intArray) { + this.intArray = intArray; + } + + void bubbleSort() { + LOG.info( "Entered the sort method."); + + for(int i = intArray.length -1; i >= 0 ; i--) { + NDC.push("i=" + i); + OUTER.debug("in outer loop."); + for(int j = 0; j < i; j++) { + NDC.push("j=" + j); + // It is poor practice to ship code with log staments in tight loops. + // We do it anyway in this example. + INNER.debug( "in inner loop."); + if(intArray[j] > intArray[j+1]) + swap(j, j+1); + NDC.pop(); + } + NDC.pop(); + } + } + + void dump() { + if(! (this.intArray instanceof int[])) { + DUMP.error("Tried to dump an uninitialized array."); + return; + } + DUMP.info("Dump of integer array:"); + for(int i = 0; i < this.intArray.length; i++) { + DUMP.info("Element [" + i + "]=" + this.intArray[i]); + } + } + + void swap(int l, int r) { + // It is poor practice to ship code with log staments in tight + // loops or code called potentially millions of times. + SWAP.debug( "Swapping intArray["+l+"]=" + intArray[l] + + " and intArray["+r+"]=" + intArray[r]); + int temp = this.intArray[l]; + this.intArray[l] = this.intArray[r]; + this.intArray[r] = temp; + } +} + diff --git a/examples/Trivial.java b/examples/Trivial.java new file mode 100644 index 0000000000..99e9978125 --- /dev/null +++ b/examples/Trivial.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package examples; + + +import org.apache.log4j.Logger; +import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.NDC; + +/** + View the source code of this a + trivial usage example. Running java examples.Trivial + should output something similar to: + +

+      0    INFO  [main] examples.Trivial (Client #45890) - Awake awake. Put on thy strength.
+      15   DEBUG [main] examples.Trivial (Client #45890 DB) - Now king David was old.
+      278  INFO  [main] examples.Trivial$InnerTrivial (Client #45890) - Entered foo.
+      293  INFO  [main] examples.Trivial (Client #45890) - Exiting Trivial.   
+   
+ +

The increasing numbers at the beginning of each line are the + times elapsed since the start of the program. The string between + the parentheses is the nested diagnostic context. + +

See {@link Sort} and {@link SortAlgo} for sligtly more elaborate + examples. + +

Note thent class files for the example code is not included in + any of the distributed log4j jar files. You will have to add the + directory /dir-where-you-unpacked-log4j/classes to + your classpath before trying out the examples. + + */ +public class Trivial { + + static Logger logger = Logger.getLogger(Trivial.class); + + public static void main(String[] args) { + BasicConfigurator.configure(); + NDC.push("Client #45890"); + + logger.info("Awake awake. Put on thy strength."); + Trivial.foo(); + InnerTrivial.foo(); + logger.info("Exiting Trivial."); + } + + static + void foo() { + NDC.push("DB"); + logger.debug("Now king David was old."); + NDC.pop(); + } + + static class InnerTrivial { + static Logger logger = Logger.getLogger(InnerTrivial.class); + + static + void foo() { + logger.info("Entered foo."); + } + } +} diff --git a/examples/customLevel/XLevel.java b/examples/customLevel/XLevel.java new file mode 100644 index 0000000000..d4d1b902f3 --- /dev/null +++ b/examples/customLevel/XLevel.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package examples.customLevel; + +import org.apache.log4j.Level; + + +/** + This class introduces a new level level called TRACE. TRACE has + lower level than DEBUG. + + */ +public class XLevel extends Level { + private static final long serialVersionUID = 2626753561969426769L; + + static public final int TRACE_INT = Level.DEBUG_INT - 1; + static public final int LETHAL_INT = Level.FATAL_INT + 1; + + + private static String TRACE_STR = "TRACE"; + private static String LETHAL_STR = "LETHAL"; + + + public static final XLevel TRACE = new XLevel(TRACE_INT, TRACE_STR, 7); + public static final XLevel LETHAL = new XLevel(LETHAL_INT, LETHAL_STR, + 0); + + + protected + XLevel(int level, String strLevel, int syslogEquiv) { + super(level, strLevel, syslogEquiv); + } + + /** + Convert the string passed as argument to a level. If the + conversion fails, then this method returns {@link #TRACE}. + */ + public + static + Level toLevel(String sArg) { + return (Level) toLevel(sArg, XLevel.TRACE); + } + + + public + static + Level toLevel(String sArg, Level defaultValue) { + + if(sArg == null) { + return defaultValue; + } + String stringVal = sArg.toUpperCase(); + + if(stringVal.equals(TRACE_STR)) { + return XLevel.TRACE; + } else if(stringVal.equals(LETHAL_STR)) { + return XLevel.LETHAL; + } + + return Level.toLevel(sArg, (Level) defaultValue); + } + + + public + static + Level toLevel(int i) throws IllegalArgumentException { + switch(i) { + case TRACE_INT: return XLevel.TRACE; + case LETHAL_INT: return XLevel.LETHAL; + } + return Level.toLevel(i); + } + +} + diff --git a/examples/src/factor/factor.html b/examples/factor.html similarity index 86% rename from examples/src/factor/factor.html rename to examples/factor.html index bf9f27ffd0..af593c7425 100644 --- a/examples/src/factor/factor.html +++ b/examples/factor.html @@ -1,4 +1,21 @@ + diff --git a/examples/factor.lcf b/examples/factor.lcf new file mode 100644 index 0000000000..bc43ba0324 --- /dev/null +++ b/examples/factor.lcf @@ -0,0 +1,45 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# +# 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 FileAppender which outputs to the file +# "factor.log". Start the server NumberCruncherServer and two +# NumberCruncherClients, and ask to factor two numbers +# near-simultaneously. Notice that the log output from these two +# requests are logged in the file factor.log. Nevertheless, the logs +# of these requests can still be distinguished given their distinct +# nested diagnostic contexts. + +log4j.appender.A1=org.apache.log4j.FileAppender +log4j.appender.A1.File=factor.log +log4j.appender.A1.layout=org.apache.log4j.PatternLayout + +# Note the %x conversion specifier for NDC printing. +log4j.appender.A1.layout.ConversionPattern=%-4r %-5p [%t] (%x) - %m\n + diff --git a/examples/lf5/InitUsingDefaultConfigurator/InitUsingDefaultConfigurator.java b/examples/lf5/InitUsingDefaultConfigurator/InitUsingDefaultConfigurator.java new file mode 100644 index 0000000000..1c54f3d733 --- /dev/null +++ b/examples/lf5/InitUsingDefaultConfigurator/InitUsingDefaultConfigurator.java @@ -0,0 +1,135 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +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 0000000000..3e6fae23f9 --- /dev/null +++ b/examples/lf5/InitUsingLog4JProperties/InitUsingLog4JProperties.java @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +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 0000000000..ac74606898 --- /dev/null +++ b/examples/lf5/InitUsingLog4JProperties/log4j.properties @@ -0,0 +1,33 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# 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 0000000000..6aac063676 --- /dev/null +++ b/examples/lf5/InitUsingMultipleAppenders/InitUsingMultipleAppenders.java @@ -0,0 +1,146 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +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 0000000000..c48666331e --- /dev/null +++ b/examples/lf5/InitUsingMultipleAppenders/example.properties @@ -0,0 +1,49 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# 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 0000000000..d1968ca3aa --- /dev/null +++ b/examples/lf5/InitUsingPropertiesFile/InitUsingPropertiesFile.java @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +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 0000000000..146dc18a3e --- /dev/null +++ b/examples/lf5/InitUsingPropertiesFile/example.properties @@ -0,0 +1,33 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# 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 0000000000..c02e8c7baa --- /dev/null +++ b/examples/lf5/InitUsingXMLPropertiesFile/InitUsingXMLPropertiesFile.java @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +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 0000000000..16f0ba007c --- /dev/null +++ b/examples/lf5/InitUsingXMLPropertiesFile/example.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/lf5/UsingLogMonitorAdapter/CustomizedLogLevels.java b/examples/lf5/UsingLogMonitorAdapter/CustomizedLogLevels.java new file mode 100644 index 0000000000..b0e9942e74 --- /dev/null +++ b/examples/lf5/UsingLogMonitorAdapter/CustomizedLogLevels.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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 0000000000..545bf3118f --- /dev/null +++ b/examples/lf5/UsingLogMonitorAdapter/UsingLogMonitorAdapter.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +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 + * + * 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 0000000000..d22a2e0df5 --- /dev/null +++ b/examples/lf5/UsingSocketAppenders/UsingSocketAppenders.java @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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.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 0000000000..37376014da --- /dev/null +++ b/examples/lf5/UsingSocketAppenders/socketclient.properties @@ -0,0 +1,33 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# 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 0000000000..f36aa7e42b --- /dev/null +++ b/examples/lf5/UsingSocketAppenders/socketserver.properties @@ -0,0 +1,35 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# 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 0000000000..6c78250c5a --- /dev/null +++ b/examples/lf5/index.html @@ -0,0 +1,28 @@ + + + + + + + +

See Examples + section in the LogFactor5 user guide. +

+ + diff --git a/examples/mycat.bad b/examples/mycat.bad new file mode 100644 index 0000000000..27ceb9ea44 --- /dev/null +++ b/examples/mycat.bad @@ -0,0 +1,32 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# The usual stuff. Note that A1 is configured in root not in "some.cat" +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 +# 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 + + + diff --git a/examples/mycat.good b/examples/mycat.good new file mode 100644 index 0000000000..76697fae7a --- /dev/null +++ b/examples/mycat.good @@ -0,0 +1,40 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Setting the logger factory to MyLoggerFactory solves the +# ClassCastException problem encountered with the "mycat.bad" +# configuration file. + +log4j.loggerFactory=examples.subclass.MyLoggerFactory + + +# The usual stuff. Note that A1 is configured in root not in "some.cat" + +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 +# 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.logger.some.cat=TRACE#examples.customLevel.XLevel + diff --git a/examples/package.html b/examples/package.html new file mode 100644 index 0000000000..944341b6fe --- /dev/null +++ b/examples/package.html @@ -0,0 +1,54 @@ + + + + + + + +

Example usage of log4j including source code. + +

Note that class files for the example code is not included in any +of the distributed log4j jar files. You will have to add the directory +/dir-where-you-unpacked-log4j/classes to your classpath +before trying out the examples. + +

This package's shows how log4j can be used to output log +statements. + +

    + +

  • See source code of Trivial.java for a trivial usage +example. + +

  • See source code of Sort.java and +SortAlgo.java to for a slightly +more advanced example. + +

  • See {@link org.apache.log4j.examples.NumberCruncherServer} for a {@link +org.apache.log4j.NDC} based technique to distinguish the log output from +requests from multiple clients. + +
+
+
+ +Last modified: Fri May 5 10:20:04 MDT 2000 + + diff --git a/examples/sort1.properties b/examples/sort1.properties new file mode 100644 index 0000000000..5f676d357e --- /dev/null +++ b/examples/sort1.properties @@ -0,0 +1,42 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# An example log4j configuration file that outputs to System.out. The +# output information consists of relative time, log level, thread +# name, logger name, nested diagnostic context and the message in that +# order. + +# For the general syntax of property based configuration files see the +# documenation of org.apache.log4j.PropertyConfigurator. + +log4j.rootLogger=DEBUG, A1 + +# A1 is set to be a ConsoleAppender which outputs to System.out. +log4j.appender.A1=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.A1.layout=org.apache.log4j.PatternLayout + +# The conversion pattern uses format specifiers. You might want to +# change the pattern an watch the output format change. +log4j.appender.A1.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n + +# In this example, we are not really interested in INNER loop or SWAP +# messages. See the effects of uncommenting and changing the levels of +# the following loggers. +# log4j.logger.org.apache.log4j.examples.SortAlgo.INNER=WARN +# log4j.logger.org.apache.log4j.examples.SortAlgo.SWAP=WARN + \ No newline at end of file diff --git a/examples/sort2.properties b/examples/sort2.properties new file mode 100644 index 0000000000..b55de06929 --- /dev/null +++ b/examples/sort2.properties @@ -0,0 +1,70 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# An example log4j configuration file that outputs both to System.out +# and a file named 'test'. + +# For the general syntax of property based configuration files see the +# documenation of org.apache.log4j.PropertyConfigurator. + +# WARNING: Location information can be useful but is very costly in +# terms of computation. + +# The root logger uses the appender called A1. + +# The root logger uses the appenders called A1 and A2. Since no level +# is specified, note the empty string between the comma (",") and the +# equals sign ("="), the level of the root logger remains +# untouched. Log4j always initializes the level for the root logger to +# DEBUG. The root logger is the only logger that has a default +# level. Bu default, all other loggers do not have an assigned level, +# such that they inherit their level instead. + +log4j.rootLogger=, A1, A2 + +# A1 is set to be ConsoleAppender sending its output to System.out +log4j.appender.A1=org.apache.log4j.ConsoleAppender + + +# A1 uses PatternLayout. +log4j.appender.A1.layout=org.apache.log4j.PatternLayout + +# The conversion pattern consists of date in ISO8601 format, level, +# thread name, logger name truncated to its rightmost two components +# and left justified to 17 characters, location information consisting +# of file name (padded to 13 characters) and line number, nested +# diagnostic context, the and the application supplied message + +log4j.appender.A1.layout.ConversionPattern=%d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n + +# Appender A2 writes to the file "test". +log4j.appender.A2=org.apache.log4j.FileAppender +log4j.appender.A2.File=test + +# Truncate 'test' if it aleady exists. +log4j.appender.A2.Append=false + +# Appender A2 uses the PatternLayout. +log4j.appender.A2.layout=org.apache.log4j.PatternLayout +log4j.appender.A2.layout.ConversionPattern=%-5r %-5p [%t] %c{2} - %m%n + + +# In this example, we are not interested in INNER loop or SWAP +# messages. You might try to set INNER and SWAP to DEBUG for more +# verbose output. + +log4j.logger.org.apache.log4j.examples.SortAlgo.INNER=INFO +log4j.logger.org.apache.log4j.examples.SortAlgo.SWAP=INFO diff --git a/examples/sort3.properties b/examples/sort3.properties new file mode 100644 index 0000000000..91b172dfab --- /dev/null +++ b/examples/sort3.properties @@ -0,0 +1,47 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# An example log4j configuration file that directs its logging output +# to a SocketAppender. The SocketAppender is configuted to send its +# output to a server running on the localhost port number 12345. + +# To test this example, you must start a log4j server with the command +# +# +# java org.apache.log4j.net.SocketServer 12345 configurationFile directory/ +# +# + +# For the general syntax of property based configuration files see +# the documenation of org.apache.log4j.PropertyConfigurator. + +# The root logger uses the appender called A1. + +log4j.rootLogger=DEBUG, A1 + +# A1 is set to be a SocketAppender sending its output to the server +running on the local host, port 12345. + +log4j.appender.A1=org.apache.log4j.net.SocketAppender +log4j.appender.A1.Port=12345 +log4j.appender.A1.RemoteHost=localhost + +# In this example, we are not interested in INNER loop or SWAP +# messages. You might try to set INNER and SWAP to DEBUG for more +# verbose output. + +log4j.logger.org.apache.log4j.examples.SortAlgo.INNER=INFO +log4j.logger.org.apache.log4j.examples.SortAlgo.SWAP=INFO diff --git a/examples/sort4.properties b/examples/sort4.properties new file mode 100644 index 0000000000..72d8a19f7e --- /dev/null +++ b/examples/sort4.properties @@ -0,0 +1,47 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Attach appender A1 to root. Set root level to Level.DEBUG. +log4j.rootLogger=DEBUG, A1 + +# A1 is set to be a FileAppender sending its output to +# System.out. However, only error messages and above will be printed +# in A1 because A1's threshold is set to Level.ERROR. + +# The fact that the root level is set to Prority.DEBUG only influences +# log requests made to the root logger. It has no influence on the +# *appenders* attached to root. + +log4j.appender.A1=org.apache.log4j.ConsoleAppender +log4j.appender.A1.Threshold=ERROR + +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%p [%t] %c{2} (%M:%L) - %m%n + +# Set the level of the logger named "org.apache.log4j.examples" to +# Level.INFO, attach appender A2. +log4j.logger.org.apache.log4j.examples=INFO, A2 + +# Appender A2 writes to the file "test" in user's home. +log4j.appender.A2=org.apache.log4j.FileAppender +log4j.appender.A2.File=${user.home}/test + +# Truncate 'test' if it aleady exists. +log4j.appender.A2.Append=false + +# Appender A2 uses the PatternLayout. +log4j.appender.A2.layout=org.apache.log4j.PatternLayout +log4j.appender.A2.layout.ConversionPattern=%5r %-5p [%t] %c{2} - %m%n diff --git a/examples/src/customLevel/XLevel.java b/examples/src/customLevel/XLevel.java deleted file mode 100644 index 0bd244a7b7..0000000000 --- a/examples/src/customLevel/XLevel.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package customLevel; - -import org.apache.log4j.Level; - -/** - This class introduces a new level level called TRACE. TRACE has - lower level than DEBUG. - - */ -public class XLevel extends Level { - public static final int TRACE_INT = Level.DEBUG_INT - 1; - public static final int LETHAL_INT = Level.FATAL_INT + 1; - private static String TRACE_STR = "TRACE"; - private static String LETHAL_STR = "LETHAL"; - public static final XLevel TRACE = new XLevel(TRACE_INT, TRACE_STR, 7); - public static final XLevel LETHAL = new XLevel(LETHAL_INT, LETHAL_STR, 0); - - protected XLevel(int level, String strLevel, int syslogEquiv) { - super(level, strLevel, syslogEquiv); - } - - /** - Convert the string passed as argument to a level. If the - conversion fails, then this method returns {@link #TRACE}. - */ - public static Level toLevel(String sArg) { - return (Level) toLevel(sArg, XLevel.TRACE); - } - - public static Level toLevel(String sArg, Level defaultValue) { - if (sArg == null) { - return defaultValue; - } - - String stringVal = sArg.toUpperCase(); - - if (stringVal.equals(TRACE_STR)) { - return XLevel.TRACE; - } else if (stringVal.equals(LETHAL_STR)) { - return XLevel.LETHAL; - } - - return Level.toLevel(sArg, (Level) defaultValue); - } - - public static Level toLevel(int i) throws IllegalArgumentException { - switch (i) { - case TRACE_INT: - return XLevel.TRACE; - - case LETHAL_INT: - return XLevel.LETHAL; - } - - return Level.toLevel(i); - } -} diff --git a/examples/src/factor/NumberCruncher.java b/examples/src/factor/NumberCruncher.java deleted file mode 100644 index 7aaaed31b7..0000000000 --- a/examples/src/factor/NumberCruncher.java +++ /dev/null @@ -1,21 +0,0 @@ - -package factor; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -/** - NumberCruncher's factor positive integers. See source code for more details. - - @author Ceki Gülcü - -*/ -public interface NumberCruncher extends Remote { - - /** - Factor a positive integer number and return its - distinct factor's as an integer array. - */ - int[] factor(int number) throws RemoteException; -} diff --git a/examples/src/factor/NumberCruncherServer.java b/examples/src/factor/NumberCruncherServer.java deleted file mode 100644 index c9d91cab0c..0000000000 --- a/examples/src/factor/NumberCruncherServer.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package factor; - -import org.apache.log4j.Logger; -import org.apache.log4j.NDC; -import org.apache.log4j.PropertyConfigurator; - -import java.rmi.Naming; -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -import java.util.Vector; - - -/** - A simple {@link NumberCruncher} implementation that logs its - progress when factoring numbers. The purpose of the whole exercise - is to show the use of nested diagnostic contexts in order to - distinguish the log output from different client requests. - -
-   Usage: java org.apache.log4j.examples.NumberCruncherServer configFile
-          where configFile is a log4j configuration file.
-   
- - We supply a simple config file factor.lcf - for directing log output to the file factor.log. - -

Try it yourself by starting a NumberCruncherServer - and make queries from multiple {@link NumberCruncherClient - NumberCruncherClients} to factor numbers. - - -

Sample output shows the log - output when two clients connect to the server near simultaneously. - -

See source code - of NumberCruncherServer for more details. - -

Note that class files for the example code is not included in - any of the distributed log4j jar files. You will have to add the - directory /dir-where-you-unpacked-log4j/classes to - your classpath before trying out the examples. - - - */ -public class NumberCruncherServer extends UnicastRemoteObject - implements NumberCruncher { - final static Logger logger = Logger.getLogger(NumberCruncherServer.class); - - public NumberCruncherServer() throws RemoteException { - } - - public int[] factor(int number) throws RemoteException { - // The client's host is an important source of information. - try { - NDC.push(getClientHost()); - } catch (java.rmi.server.ServerNotActiveException e) { - // we are being called from same VM - NDC.push("localhost"); - } - - // The information contained within the request is another source of - // distinctive information. It might reveal the users name, date of request, - // request ID etc. In servlet type environments, much information is - // contained in cookies. - NDC.push(String.valueOf(number)); - - logger.info("Beginning to factor."); - - if (number <= 0) { - throw new IllegalArgumentException( - number + " is not a positive integer."); - } else if (number == 1) { - return new int[] { 1 }; - } - - Vector factors = new Vector(); - int n = number; - - for (int i = 2; (i <= n) && ((i * i) <= number); i++) { - // It is bad practice to place log requests within tight loops. - // It is done here to show interleaved log output from - // different requests. - logger.debug("Trying to see if " + i + " is a factor."); - - if ((n % i) == 0) { - logger.info("Found factor " + i); - factors.addElement(new Integer(i)); - - do { - n /= i; - } while ((n % i) == 0); - } - - // Placing artificial delays in tight-loops will also lead to sub-optimal - // resuts. :-) - delay(100); - } - - if (n != 1) { - logger.info("Found factor " + n); - factors.addElement(new Integer(n)); - } - - int len = factors.size(); - - int[] result = new int[len]; - - for (int i = 0; i < len; i++) { - result[i] = ((Integer) factors.elementAt(i)).intValue(); - } - - // Before leaving a thread we call NDC.remove. This deletes the reference - // to the thread in the internal hash table. Version 0.8.5 introduces a - // a lazy removal mechanism in case you forget to call remove when - // exiting a thread. See the java documentation in NDC.remove for further - // details. - NDC.remove(); - - return result; - } - - static void usage(String msg) { - System.err.println(msg); - System.err.println( - "Usage: java org.apache.log4j.examples.NumberCruncherServer configFile\n" - + " where configFile is a log4j configuration file."); - System.exit(1); - } - - public static void delay(int millis) { - try { - Thread.sleep(millis); - } catch (InterruptedException e) { - } - } - - public static void main(String[] args) { - if (args.length != 1) { - usage("Wrong number of arguments."); - } - - NumberCruncherServer ncs; - PropertyConfigurator.configure(args[0]); - - try { - ncs = new NumberCruncherServer(); - Naming.rebind("Factor", ncs); - logger.info("NumberCruncherServer bound and ready to serve."); - } catch (Exception e) { - logger.error("Could not bind NumberCruncherServer.", e); - return; - } - NumberCruncherClient.loop(ncs); - } -} diff --git a/examples/src/factor/factor.lcf b/examples/src/factor/factor.lcf deleted file mode 100644 index 232e66fd99..0000000000 --- a/examples/src/factor/factor.lcf +++ /dev/null @@ -1,27 +0,0 @@ -# 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 FileAppender which outputs to the file -# "factor.log". Start the server NumberCruncherServer and two -# NumberCruncherClients, and ask to factor two numbers -# near-simultaneously. Notice that the log output from these two -# requests are logged in the file factor.log. Nevertheless, the logs -# of these requests can still be distinguished given their distinct -# nested diagnostic contexts. - -log4j.appender.A1=org.apache.log4j.FileAppender -log4j.appender.A1.File=factor.log -log4j.appender.A1.layout=org.apache.log4j.PatternLayout - -# Note the %x conversion specifier for NDC printing. -log4j.appender.A1.layout.ConversionPattern=%-4r %-5p [%t] (%x) - %m\n - diff --git a/examples/src/joran/calculator/AddAction.java b/examples/src/joran/calculator/AddAction.java deleted file mode 100644 index 7c0af37f00..0000000000 --- a/examples/src/joran/calculator/AddAction.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package joran.calculator; - -import org.apache.log4j.joran.action.Action; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.spi.ErrorItem; - -import org.xml.sax.Attributes; - -import java.util.EmptyStackException; - - -/** - * This action adds the two integers at the top of the stack (they are removed) - * and pushes the result to the top the stack. - * - * @author Ceki Gülcü - */ -public class AddAction extends Action { - - public void begin(ExecutionContext ec, String name, Attributes attributes) { - int first = fetchInteger(ec); - int second = fetchInteger(ec); - // Push the result of the addition for the following actions. - ec.pushObject(new Integer(first + second)); - } - - /** - * Pop the Integer object at the top of the stack. - * This code illustrates usage of Joran's error handling paradigm. - */ - int fetchInteger(ExecutionContext ec) { - int result = 0; - - try { - // Pop the object at the top of the exection context stack. - Object o1 = ec.popObject(); - - if (o1 instanceof Integer) { - result = ((Integer) o1).intValue(); - } else { - String errMsg = - "Object [" + o1 - + "] currently at the top of the stack is not an integer."; - ec.addError(new ErrorItem(errMsg)); - throw new IllegalArgumentException(errMsg); - } - } catch (EmptyStackException ese) { - ec.addError( - new ErrorItem("Expecting an integer on the execution stack.")); - throw ese; - } - return result; - } - - public void end(ExecutionContext ec, String name) { - // Nothing to do here. - // In general, the end() method of actions associated with elements - // having no children do not need to perform any processing in their - // end() method. - } -} diff --git a/examples/src/joran/calculator/Calculator1.java b/examples/src/joran/calculator/Calculator1.java deleted file mode 100644 index 2d84d7b54e..0000000000 --- a/examples/src/joran/calculator/Calculator1.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package joran.calculator; - -import java.util.List; - -import org.apache.log4j.joran.spi.Interpreter; -import org.apache.log4j.joran.spi.Pattern; -import org.apache.log4j.joran.spi.RuleStore; -import org.apache.log4j.joran.spi.SimpleRuleStore; - -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - - -/** - * This examples illustrates collaboration between multiple actions through the - * common execution context stack. - * - * The first and only argument of this application must be the path to - * the XML file to interpret. There are sample XML files in the - * examples/src/joran/calculator/ directory. - * - * For example, - * -

-    java joran.calculator.Calculator1 examples/src/joran/calculator/calculator1.xml
-
- * - * Please refer to the comments in the source code for more information. - * - * @author Ceki Güulcü - */ -public class Calculator1 { - - - public static void main(String[] args) throws Exception { - // Create a simple rule store where pattern and action associations will - // be kept. This is a basic requirement before invoking a Joran Interpreter. - RuleStore ruleStore = new SimpleRuleStore(); - - // Associate "/computation" pattern with ComputationAction1 - ruleStore.addRule(new Pattern("/computation"), new ComputationAction1()); - - // Other associations - ruleStore.addRule(new Pattern("/computation/literal"), new LiteralAction()); - ruleStore.addRule(new Pattern("/computation/add"), new AddAction()); - ruleStore.addRule(new Pattern("/computation/multiply"), new MultiplyAction()); - - // Create a new Joran Interpreter and hand it our simple rule store. - Interpreter ji = new Interpreter(ruleStore); - - // Create a SAX parser - SAXParserFactory spf = SAXParserFactory.newInstance(); - SAXParser saxParser = spf.newSAXParser(); - - // Parse the file given as the application's first argument and - // set the SAX ContentHandler to the Joran Interpreter we just created. - saxParser.parse(args[0], ji); - - // The file has been parsed and interpreted. We now print any errors that - // might have occured. - List errorList = ji.getExecutionContext().getErrorList(); - if(errorList.size() > 0) { - System.out.println("The following errors occured:"); - for(int i = 0; i < errorList.size(); i++) { - System.out.println("\t"+errorList.get(i)); - } - } - } -} diff --git a/examples/src/joran/calculator/Calculator2.java b/examples/src/joran/calculator/Calculator2.java deleted file mode 100644 index 8fd077446d..0000000000 --- a/examples/src/joran/calculator/Calculator2.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package joran.calculator; - -import java.util.List; - -import org.apache.log4j.joran.spi.Interpreter; -import org.apache.log4j.joran.spi.Pattern; -import org.apache.log4j.joran.spi.RuleStore; -import org.apache.log4j.joran.spi.SimpleRuleStore; - -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - - -/** - * This examples illustrates collaboration between multiple actions through the - * common execution context stack. - * - * It differs from Calculator1 in that it supoorts arbitrary nesting of - * computation elements. - * - * You can test this application with the sample XML file calculator3.xml. - * - * @author Ceki Güulcü - */ -public class Calculator2 { - public static void main(String[] args) throws Exception { - - RuleStore ruleStore = new SimpleRuleStore(); - - // Note the wild card character '*', in the paterns, signifying any level - // of nesting. - ruleStore.addRule(new Pattern("*/computation"), new ComputationAction2()); - - ruleStore.addRule(new Pattern("*/computation/literal"), new LiteralAction()); - ruleStore.addRule(new Pattern("*/computation/add"), new AddAction()); - ruleStore.addRule(new Pattern("*/computation/multiply"), new MultiplyAction()); - - // Create a new Joran Interpreter and hand it our simple rule store. - Interpreter ji = new Interpreter(ruleStore); - - // Create a SAX parser - SAXParserFactory spf = SAXParserFactory.newInstance(); - SAXParser saxParser = spf.newSAXParser(); - - // Parse the file given as the application's first argument and - // set the SAX ContentHandler to the Joran Interpreter we just created. - saxParser.parse(args[0], ji); - - // The file has been parsed and interpreted. We now print any errors that - // might have occured. - List errorList = ji.getExecutionContext().getErrorList(); - if(errorList.size() > 0) { - System.out.println("The following errors occured:"); - for(int i = 0; i < errorList.size(); i++) { - System.out.println("\t"+errorList.get(i)); - } - } - } -} diff --git a/examples/src/joran/calculator/ComputationAction1.java b/examples/src/joran/calculator/ComputationAction1.java deleted file mode 100644 index d163663df4..0000000000 --- a/examples/src/joran/calculator/ComputationAction1.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package joran.calculator; - -import org.apache.log4j.helpers.Option; -import org.apache.log4j.joran.action.Action; -import org.apache.log4j.joran.spi.ExecutionContext; - -import org.xml.sax.Attributes; - - -/** - * ComputationAction1 will print the result of the compuration made by - * children elements but only if the compuration itself is named, that is if the - * name attribute of the associated computation element is not null. In other - * words, anonymous computations will not print their result. - * - * @author Ceki Gülcü - */ -public class ComputationAction1 extends Action { - public static String NAME_ATR = "name"; - - String nameStr; - - /** - * Store the value of the name attribute for future use. - */ - public void begin(ExecutionContext ec, String name, Attributes attributes) { - nameStr = attributes.getValue(NAME_ATR); - } - - /** - * Children elements have been processed. The sesults should be an integer - * placed at the top of the execution stack. - * - * This value will be printed on the console but only if the action is - * named. Anonymous computation will not print their result. - */ - public void end(ExecutionContext ec, String name) { - if (Option.isEmpty(nameStr)) { - // nothing to do - } else { - Integer i = (Integer) ec.peekObject(); - System.out.println( - "The computation named [" + nameStr + "] resulted in the value " + i); - } - } -} diff --git a/examples/src/joran/calculator/ComputationAction2.java b/examples/src/joran/calculator/ComputationAction2.java deleted file mode 100644 index 869603f343..0000000000 --- a/examples/src/joran/calculator/ComputationAction2.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package joran.calculator; - -import java.util.Stack; - -import org.apache.log4j.helpers.Option; -import org.apache.log4j.joran.action.Action; -import org.apache.log4j.joran.spi.ExecutionContext; - -import org.xml.sax.Attributes; - - -/** - * ComputationAction2 will print the result of the compuration made by - * children elements but only if the compuration itself is named, that is if the - * name attribute of the associated computation element is not null. In other - * words, anonymous computations will not print their result. - * - * ComputationAction2 differs from ComputationAction1 in its handling of - * instance variables. ComputationAction1 has a simple nameStr - * instance variable. This variable is set when the begin() method is called - * and then later used within the end() method. - * - * This simple approach works properly if the begin() and end() - * method of a given action are expected to be called in sequence. However, - * there are situations where the begin() method of the same action instance is - * invoked multiple times before the matching end() method is invoked. - * - * When this happens, the second call to begin() overwrites values set by - * the first invocation to begin(). The solution is to save parameter values - * into a separate stack. The well-formedness of XML will guarantee that a value - * saved by one begin() will be consumed only by the matching end() method. - * - * Note that in the vast majority of cases there is no need to resort to a - * separate stack for each variable. The situation of successibe begin() - * invocations can only occur if: - * - * 1) the associated pattern contains a wildcard, i.e. the * character - * - * and - * - * 2) the associated element tag can contain itself as a child - * - * For example, "*/computation" pattern means that computations can contain - * other computation elements as children. - * - * @author Ceki Gülcü - */ -public class ComputationAction2 extends Action { - public static String NAME_ATR = "name"; - - Stack nameStrStack = new Stack(); - - - public void begin(ExecutionContext ec, String name, Attributes attributes) { - String nameStr = attributes.getValue(NAME_ATR); - // save nameStr value in a special stack. Note that the value is saved - // even if it is empty or null. - nameStrStack.push(nameStr); - } - - public void end(ExecutionContext ec, String name) { - // pop nameStr value from the special stack - String nameStr = (String) nameStrStack.pop(); - - if (Option.isEmpty(nameStr)) { - // nothing to do - } else { - Integer i = (Integer) ec.peekObject(); - System.out.println( - "The computation named [" + nameStr + "] resulted in the value " + i); - } - } -} diff --git a/examples/src/joran/calculator/LiteralAction.java b/examples/src/joran/calculator/LiteralAction.java deleted file mode 100644 index d6b9cbecc3..0000000000 --- a/examples/src/joran/calculator/LiteralAction.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package joran.calculator; - -import org.apache.log4j.helpers.Option; -import org.apache.log4j.joran.action.Action; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.spi.ErrorItem; - -import org.xml.sax.Attributes; - - -/** - * - * This action converts the value attribute of the associated element to - * an integer and pushes the resulting Integer object on top of the execution - * context stack. - * - * It also illustrates usage of Joran's error handling paradigm. - * - * @author Ceki Gülcü - */ -public class LiteralAction extends Action { - public static String VALUE_ATR = "value"; - - public void begin(ExecutionContext ec, String name, Attributes attributes) { - String valueStr = attributes.getValue(VALUE_ATR); - - if (Option.isEmpty(valueStr)) { - ec.addError( - new ErrorItem("The literal action requires a value attribute")); - return; - } - - try { - Integer i = Integer.valueOf(valueStr); - ec.pushObject(i); - } catch (NumberFormatException nfe) { - ec.addError( - new ErrorItem( - "The value [" + valueStr + "] could not be converted to an Integer", - nfe)); - throw nfe; - } - } - - public void end(ExecutionContext ec, String name) { - // Nothing to do here. - // In general, the end() method of actions associated with elements - // having no children do not need to perform any processing in their - // end() method. - } -} diff --git a/examples/src/joran/calculator/MultiplyAction.java b/examples/src/joran/calculator/MultiplyAction.java deleted file mode 100644 index 2c0c474ac3..0000000000 --- a/examples/src/joran/calculator/MultiplyAction.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package joran.calculator; - -import org.apache.log4j.joran.action.Action; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.spi.ErrorItem; - -import org.xml.sax.Attributes; - -import java.util.EmptyStackException; - - -/** - * - * This action multiplies the two integers at the top of the stack (they are removed) - * and pushes the result on top the stack. - * - * @author Ceki Gülcü - */ -public class MultiplyAction extends Action { - - - public void begin(ExecutionContext ec, String name, Attributes attributes) { - int first = fetchInteger(ec); - int second = fetchInteger(ec); - ec.pushObject(new Integer(first * second)); - } - - /** - * Pop the Integer object at the top of the stack. - * This code illustrates usage of Joran's error handling paradigm. - */ - int fetchInteger(ExecutionContext ec) { - int result = 0; - - try { - Object o1 = ec.popObject(); - - if (o1 instanceof Integer) { - result = ((Integer) o1).intValue(); - } else { - String errMsg = - "Object [" + o1 - + "] currently at the top of the stack is not an integer."; - ec.addError(new ErrorItem(errMsg)); - throw new IllegalArgumentException(errMsg); - } - } catch (EmptyStackException ese) { - ec.addError( - new ErrorItem("Expecting an integer on the execution stack.")); - throw ese; - } - return result; - } - - public void end(ExecutionContext ec, String name) { - // Nothing to do here. - // In general, the end() method of actions associated with elements - // having no children do not need to perform any processing in their - // end() method. - } -} diff --git a/examples/src/joran/calculator/calculator1.xml b/examples/src/joran/calculator/calculator1.xml deleted file mode 100644 index 9a135e3190..0000000000 --- a/examples/src/joran/calculator/calculator1.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/examples/src/joran/calculator/calculator2.xml b/examples/src/joran/calculator/calculator2.xml deleted file mode 100644 index 4a96c621ea..0000000000 --- a/examples/src/joran/calculator/calculator2.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/src/joran/calculator/calculator3.xml b/examples/src/joran/calculator/calculator3.xml deleted file mode 100644 index ed02b503d0..0000000000 --- a/examples/src/joran/calculator/calculator3.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/src/joran/helloWorld/HelloWorld.java b/examples/src/joran/helloWorld/HelloWorld.java deleted file mode 100644 index 48ae44c280..0000000000 --- a/examples/src/joran/helloWorld/HelloWorld.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package joran.helloWorld; - -import org.apache.log4j.joran.spi.Interpreter; -import org.apache.log4j.joran.spi.Pattern; -import org.apache.log4j.joran.spi.RuleStore; -import org.apache.log4j.joran.spi.SimpleRuleStore; - -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - - -/** - * - * A hello world example using Joran. - * - * The first and only argument of this application must be the path to - * the XML file to interpret. - * - * For example, - * -
-    java joran.helloWorld.HelloWorld examples/src/joran/helloWorld/hello.xml
-
- * - * @author Ceki - */ -public class HelloWorld { - public static void main(String[] args) throws Exception { - // Create a simple rule store where pattern and action associations will - // be kept. - RuleStore ruleStore = new SimpleRuleStore(); - - // Associate "hello-world" pattern with HelloWorldAction - ruleStore.addRule(new Pattern("hello-world"), new HelloWorldAction()); - - // Create a new Joran Interpreter and hand it our simple rule store. - Interpreter ji = new Interpreter(ruleStore); - - // Create a SAX parser - SAXParserFactory spf = SAXParserFactory.newInstance(); - SAXParser saxParser = spf.newSAXParser(); - - // Parse the file given as the application's first argument and - // set the SAX ContentHandler to the Joran Interpreter we just created. - saxParser.parse(args[0], ji); - } -} diff --git a/examples/src/joran/helloWorld/HelloWorldAction.java b/examples/src/joran/helloWorld/HelloWorldAction.java deleted file mode 100644 index b91a21dd0f..0000000000 --- a/examples/src/joran/helloWorld/HelloWorldAction.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package joran.helloWorld; - -import org.apache.log4j.joran.action.Action; -import org.apache.log4j.joran.spi.ExecutionContext; - -import org.xml.sax.Attributes; - - -/** - * A trivial action that writes "Hello world" on the console. - * - * See the HelloWorld class for integrating with Joran. - * - * @author Ceki Gülcü - */ -public class HelloWorldAction extends Action { - public void begin(ExecutionContext ec, String name, Attributes attributes) { - System.out.println("Hello World"); - } - - public void end(ExecutionContext ec, String name) { - } -} diff --git a/examples/src/joran/helloWorld/hello.xml b/examples/src/joran/helloWorld/hello.xml deleted file mode 100644 index bf66dd4d36..0000000000 --- a/examples/src/joran/helloWorld/hello.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/examples/src/joran/implicit/NOPAction.java b/examples/src/joran/implicit/NOPAction.java deleted file mode 100644 index 3af3feac72..0000000000 --- a/examples/src/joran/implicit/NOPAction.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package joran.implicit; - -import org.apache.log4j.joran.action.Action; -import org.apache.log4j.joran.spi.ExecutionContext; - -import org.xml.sax.Attributes; - - - -/** - * No operation (NOP) action that does strictly nothing. - * - * @author Ceki Gülcü - */ -public class NOPAction extends Action { - - public void begin(ExecutionContext ec, String name, Attributes attributes) { - } - - - public void end(ExecutionContext ec, String name) { - } -} diff --git a/examples/src/joran/implicit/PrintMe.java b/examples/src/joran/implicit/PrintMe.java deleted file mode 100644 index 3d4a415c6d..0000000000 --- a/examples/src/joran/implicit/PrintMe.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package joran.implicit; - -import org.apache.log4j.joran.spi.Interpreter; -import org.apache.log4j.joran.spi.Pattern; -import org.apache.log4j.joran.spi.RuleStore; -import org.apache.log4j.joran.spi.SimpleRuleStore; - -import java.util.List; - -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - - -/** - * This example illustrates the usage of implcit actions. - * - * The crucial point to remember about implicit actions is that they - * are not associated with a pattern. Moreover, they are added directly to - * a Joran Interpreter instead of a rule store. - * - * @author Ceki Güulcü - */ -public class PrintMe { - - - public static void main(String[] args) throws Exception { - // Uncomment the following line in order to enable log statements generated - // from joran itself. - - // org.apache.log4j.BasicConfigurator.configure(); - - RuleStore ruleStore = new SimpleRuleStore(); - - // we start with the rule for the top-most (root) element - ruleStore.addRule(new Pattern("*/foo"), new NOPAction()); - - - // Create a new Joran Interpreter and hand it our simple rule store. - Interpreter ji = new Interpreter(ruleStore); - - // --------------------------+ - // Add an implicit action. | - // --------------------------+ - ji.addImplicitAction(new PrintMeImplicitAction()); - - // Create a SAX parser - SAXParserFactory spf = SAXParserFactory.newInstance(); - SAXParser saxParser = spf.newSAXParser(); - - // Parse the file given as the application's first argument and - // set the SAX ContentHandler to the Joran Interpreter we just created. - saxParser.parse(args[0], ji); - - // The file has been parsed and interpreted. We now print any errors that - // might have occured. - List errorList = ji.getExecutionContext().getErrorList(); - - if (errorList.size() > 0) { - System.out.println("The following errors occured:"); - - for (int i = 0; i < errorList.size(); i++) { - System.out.println("\t" + errorList.get(i)); - } - } - } -} diff --git a/examples/src/joran/implicit/PrintMeImplicitAction.java b/examples/src/joran/implicit/PrintMeImplicitAction.java deleted file mode 100644 index 87de90844e..0000000000 --- a/examples/src/joran/implicit/PrintMeImplicitAction.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package joran.implicit; - -import org.apache.log4j.joran.action.ImplicitAction; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.joran.spi.Pattern; - -import org.xml.sax.Attributes; - - - -/** - * - * A rather trivial implicit action which is applicable as soon as an - * element has a printme attribute set to true. - * - * @author Ceki Gülcü - */ -public class PrintMeImplicitAction extends ImplicitAction { - - public boolean isApplicable( - Pattern pattern, Attributes attributes, ExecutionContext ec) { - String printmeStr = attributes.getValue("printme"); - - return Boolean.valueOf(printmeStr).booleanValue(); - } - - public void begin(ExecutionContext ec, String name, Attributes attributes) { - System.out.println("Element <"+name+"> asked to be printed."); - } - - - public void end(ExecutionContext ec, String name) { - } -} diff --git a/examples/src/joran/implicit/implicit1.xml b/examples/src/joran/implicit/implicit1.xml deleted file mode 100644 index 11837809da..0000000000 --- a/examples/src/joran/implicit/implicit1.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/src/joran/newRule/NewRuleCalculator.java b/examples/src/joran/newRule/NewRuleCalculator.java deleted file mode 100644 index 5580c32904..0000000000 --- a/examples/src/joran/newRule/NewRuleCalculator.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package joran.newRule; - -import joran.calculator.ComputationAction2; - -import org.apache.log4j.joran.action.NewRuleAction; -import org.apache.log4j.joran.spi.Interpreter; -import org.apache.log4j.joran.spi.Pattern; -import org.apache.log4j.joran.spi.RuleStore; -import org.apache.log4j.joran.spi.SimpleRuleStore; - -import java.util.List; - -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - - -/** - * This example illustrates the usage of NewRuleAction which allows the Joran - * interpreter to learn new rules on the fly from the XML file being - * interpreted. - * - * This example relies heavily on the code from the joran.calculator package. - * - * @author Ceki Güulcü - */ -public class NewRuleCalculator { - public static void main(String[] args) throws Exception { - // Uncomment the following line in order to enable log statements generated - // from joran itself. - // org.apache.log4j.BasicConfigurator.configure(); - - // As usual, we create a simple rule store. - RuleStore ruleStore = new SimpleRuleStore(); - - // we start with the rule for the top-most (root) element - ruleStore.addRule(new Pattern("*/computation"), new ComputationAction2()); - - // Associate "/new-rule" pattern with NewRuleAction from the - // org.apache.joran.action package. - // - // We will let the XML file to teach the Joran interpreter about new rules - ruleStore.addRule( - new Pattern("/computation/new-rule"), new NewRuleAction()); - - // Create a new Joran Interpreter and hand it our simple rule store. - Interpreter ji = new Interpreter(ruleStore); - - // Create a SAX parser - SAXParserFactory spf = SAXParserFactory.newInstance(); - SAXParser saxParser = spf.newSAXParser(); - - // Parse the file given as the application's first argument and - // set the SAX ContentHandler to the Joran Interpreter we just created. - saxParser.parse(args[0], ji); - - - // The file has been parsed and interpreted. We now print any errors that - // might have occured. - List errorList = ji.getExecutionContext().getErrorList(); - - if (errorList.size() > 0) { - System.out.println("The following errors occured:"); - - for (int i = 0; i < errorList.size(); i++) { - System.out.println("\t" + errorList.get(i)); - } - } - } -} diff --git a/examples/src/objectBased/Base.java b/examples/src/objectBased/Base.java deleted file mode 100644 index 5cb8d2450b..0000000000 --- a/examples/src/objectBased/Base.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package objectBased; - -import org.apache.log4j.Logger; - - -/** - * - * An almost trivially simple Base class. - * - * It uses the {@link #getLogger} method to retreive the logger to use. This - * method can be overrriden by derived clases to acheive "object" based logging. - * - * @author Scott Melcher - * @author Gülcü - */ -public class Base { - static Logger logger = Logger.getLogger(Base.class); - - public void myMethod() { - getLogger().debug("logging message"); - } - - public Logger getLogger() { - System.out.println("Base.getLogger called"); - return Base.logger; - } - -} diff --git a/examples/src/objectBased/ChildOne.java b/examples/src/objectBased/ChildOne.java deleted file mode 100644 index 0fe6d06cd6..0000000000 --- a/examples/src/objectBased/ChildOne.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package objectBased; - -import org.apache.log4j.Logger; - -public class ChildOne extends Base { - static Logger logger = Logger.getLogger(ChildOne.class); - - public void execute() { - myMethod(); - } - - public Logger getLogger() { - System.out.println("ChildOne.getLogger called"); - return ChildOne.logger; - } -} diff --git a/examples/src/objectBased/ChildTwo.java b/examples/src/objectBased/ChildTwo.java deleted file mode 100644 index bfe0dbbf30..0000000000 --- a/examples/src/objectBased/ChildTwo.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package objectBased; - -import org.apache.log4j.Logger; - -public class ChildTwo extends Base { - static Logger logger = Logger.getLogger(ChildTwo.class); - - public void execute() { - myMethod(); - } - - public Logger getLogger() { - System.out.println("ChildTwo.getLogger called"); - return ChildTwo.logger; - } -} diff --git a/examples/src/objectBased/Test.java b/examples/src/objectBased/Test.java deleted file mode 100644 index 6a888ee1ac..0000000000 --- a/examples/src/objectBased/Test.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package objectBased; - -import org.apache.log4j.BasicConfigurator; -import org.apache.log4j.Level; -import org.apache.log4j.Logger; - - -public class Test { - public static void main(String[] args) { - BasicConfigurator.configure(); - - Logger logger_c2 = Logger.getLogger(ChildTwo.class); - logger_c2.setLevel(Level.INFO); - - - ChildOne c1 = new ChildOne(); - c1.execute(); - - - ChildTwo c2 = new ChildTwo(); - c2.execute(); - } -} diff --git a/examples/src/package.html b/examples/src/package.html deleted file mode 100644 index def43d8851..0000000000 --- a/examples/src/package.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - -

Example usage of log4j including source code. - -

Note that class files for the example code is not included in any -of the distributed log4j jar files. You will have to add the directory -/dir-where-you-unpacked-log4j/classes to your classpath -before trying out the examples. - -

This package's shows how log4j can be used to output log -statements. - -

    - -

  • See source code of Trivial.java for a trivial usage -example. - -

  • See source code of Sort.java and -SortAlgo.java to for a slightly -more advanced example. - -

  • See {@link org.apache.log4j.examples.NumberCruncherServer} for a {@link -org.apache.log4j.NDC} based technique to distinguish the log output from -requests from multiple clients. - -
-
-
- -Last modified: Fri May 5 10:20:04 MDT 2000 - - diff --git a/examples/src/pattern/CountingPatternConverter.java b/examples/src/pattern/CountingPatternConverter.java deleted file mode 100644 index 1ea9923d5c..0000000000 --- a/examples/src/pattern/CountingPatternConverter.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package pattern; - -import org.apache.log4j.pattern.LoggingEventPatternConverter; -import org.apache.log4j.spi.LoggingEvent; - - -public final class CountingPatternConverter extends LoggingEventPatternConverter { - - private int counter = 0; - - public CountingPatternConverter() { - super("Count", "count"); - } - - public void format(final LoggingEvent event, final StringBuffer toAppendTo) { - toAppendTo.append(String.valueOf(++counter)); - } - -} diff --git a/examples/src/pattern/LearnNewWord.java b/examples/src/pattern/LearnNewWord.java deleted file mode 100644 index 30451287a8..0000000000 --- a/examples/src/pattern/LearnNewWord.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package pattern; - -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.joran.JoranConfigurator; - -/** - * - * Example showing how to extend PatternLayout to recognize additional - * conversion words without through a configuration file. - * - *

In this case have PatternLayout recognize %counter conversion word. - * It outputs the value of an internal counter which is also incremented at - * each call. - * - * @author Ceki Gülcü - */ - -public class LearnNewWord { - - public static void main(String[] args) { - if (args.length != 1) { - System.err.println("Usage: java " + LearnNewWord.class.getName() + - " configFile"); - - } - - JoranConfigurator joran = new JoranConfigurator(); - - joran.doConfigure(args[0], LogManager.getLoggerRepository()); - joran.dumpErrors(); - - Logger logger = Logger.getLogger("some.cat"); - logger.debug("Hello, log"); - logger.info("Hello again..."); - } -} diff --git a/examples/src/pattern/log4j-config.xml b/examples/src/pattern/log4j-config.xml deleted file mode 100644 index 8c1e492020..0000000000 --- a/examples/src/pattern/log4j-config.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/src/sort/Sort.java b/examples/src/sort/Sort.java deleted file mode 100644 index 6cc7d15974..0000000000 --- a/examples/src/sort/Sort.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sort; - -import org.apache.log4j.Logger; -import org.apache.log4j.PropertyConfigurator; - - -/** - Example code for log4j to viewed in conjunction with the {@link - examples.SortAlgo SortAlgo} class. - -

This program expects a configuration file name as its first - argument, and the size of the array to sort as the second and last - argument. See its source - code for more details. - -

Play around with different values in the configuration file and - watch the changing behavior. - -

Example configuration files can be found in sort1.properties, sort2.properties, sort3.properties and sort4.properties are supplied with the - package. - -

If you are also interested in logging performance, then have - look at the {@link org.apache.log4j.performance.Logging} class. - - @author Ceki Gülcü */ -public class Sort { - static Logger logger = Logger.getLogger(Sort.class.getName()); - - public static void main(String[] args) { - if (args.length != 2) { - usage("Incorrect number of parameters."); - } - - int arraySize = -1; - - try { - arraySize = Integer.valueOf(args[1]).intValue(); - - if (arraySize <= 0) { - usage("Negative array size."); - } - } catch (java.lang.NumberFormatException e) { - usage("Could not number format [" + args[1] + "]."); - } - - PropertyConfigurator.configure(args[0]); - - int[] intArray = new int[arraySize]; - - logger.info( - "Populating an array of " + arraySize + " elements in" - + " reverse order."); - - for (int i = arraySize - 1; i >= 0; i--) { - intArray[i] = arraySize - i - 1; - } - - SortAlgo sa1 = new SortAlgo(intArray); - sa1.bubbleSort(); - sa1.dump(); - - // We intentionally initilize sa2 with null. - SortAlgo sa2 = new SortAlgo(null); - logger.info("The next log statement should be an error message."); - sa2.dump(); - logger.info("Exiting main method."); - } - - static void usage(String errMsg) { - System.err.println(errMsg); - System.err.println( - "\nUsage: java org.apache.examples.Sort " + "configFile ARRAY_SIZE\n" - + "where configFile is a configuration file\n" - + " ARRAY_SIZE is a positive integer.\n"); - System.exit(1); - } -} diff --git a/examples/src/sort/SortAlgo.java b/examples/src/sort/SortAlgo.java deleted file mode 100644 index 630dacd85d..0000000000 --- a/examples/src/sort/SortAlgo.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sort; - -import org.apache.log4j.Logger; -import org.apache.log4j.NDC; - - -/** - Example code for log4j to viewed in conjunction with the {@link - examples.Sort Sort} class. - -

SortAlgo uses the bubble sort algorithm to sort an integer - array. See also its source - code. - - @author Ceki Gülcü */ -public class SortAlgo { - static final String className = SortAlgo.class.getName(); - static final Logger CAT = Logger.getLogger(className); - static final Logger OUTER = Logger.getLogger(className + ".OUTER"); - static final Logger INNER = Logger.getLogger(className + ".INNER"); - static final Logger DUMP = Logger.getLogger(className + ".DUMP"); - static final Logger SWAP = Logger.getLogger(className + ".SWAP"); - int[] intArray; - - SortAlgo(int[] intArray) { - this.intArray = intArray; - } - - void bubbleSort() { - CAT.info("Entered the sort method."); - - for (int i = intArray.length - 1; i >= 0; i--) { - NDC.push("i=" + i); - OUTER.debug("in outer loop."); - for (int j = 0; j < i; j++) { - NDC.push("j=" + j); - // It is poor practice to ship code with log staments in tight loops. - // We do it anyway in this example. - INNER.debug("in inner loop."); - if (intArray[j] > intArray[j + 1]) { - swap(j, j + 1); - } - NDC.pop(); - } - NDC.pop(); - } - } - - void dump() { - if (!(this.intArray instanceof int[])) { - DUMP.error("Tried to dump an uninitialized array."); - return; - } - DUMP.info("Dump of integer array:"); - for (int i = 0; i < this.intArray.length; i++) { - DUMP.info("Element [" + i + "]=" + this.intArray[i]); - } - } - - void swap(int l, int r) { - // It is poor practice to ship code with log staments in tight - // loops or code called potentially millions of times. - SWAP.debug( - "Swapping intArray[" + l + "]=" + intArray[l] + " and intArray[" + r - + "]=" + intArray[r]); - int temp = this.intArray[l]; - this.intArray[l] = this.intArray[r]; - this.intArray[r] = temp; - } -} diff --git a/examples/src/sort/sort1.properties b/examples/src/sort/sort1.properties deleted file mode 100644 index 9fe38d85a6..0000000000 --- a/examples/src/sort/sort1.properties +++ /dev/null @@ -1,26 +0,0 @@ -# An example log4j configuration file that outputs to System.out. The -# output information consists of relative time, log level, thread -# name, logger name, nested diagnostic context and the message in that -# order. - -# For the general syntax of property based configuration files see the -# documenation of org.apache.log4j.PropertyConfigurator. - -log4j.rootLogger=DEBUG, A1 - -# A1 is set to be a ConsoleAppender which outputs to System.out. -log4j.appender.A1=org.apache.log4j.ConsoleAppender - -# A1 uses PatternLayout. -log4j.appender.A1.layout=org.apache.log4j.PatternLayout - -# The conversion pattern uses format specifiers. You might want to -# change the pattern an watch the output format change. -log4j.appender.A1.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n - -# In this example, we are not really interested in INNER loop or SWAP -# messages. See the effects of uncommenting and changing the levels of -# the following loggers. -# log4j.logger.org.apache.log4j.examples.SortAlgo.INNER=WARN -# log4j.logger.org.apache.log4j.examples.SortAlgo.SWAP=WARN - diff --git a/examples/src/sort/sort2.properties b/examples/src/sort/sort2.properties deleted file mode 100644 index dfbc3437fa..0000000000 --- a/examples/src/sort/sort2.properties +++ /dev/null @@ -1,55 +0,0 @@ -# An example log4j configuration file that outputs both to System.out -# and a file named 'test'. - -# For the general syntax of property based configuration files see the -# documenation of org.apache.log4j.PropertyConfigurator. - -# WARNING: Location information can be useful but is very costly in -# terms of computation. - -# The root logger uses the appender called A1. - -# The root logger uses the appenders called A1 and A2. Since no level -# is specified, note the empty string between the comma (",") and the -# equals sign ("="), the level of the root logger remains -# untouched. Log4j always initializes the level for the root logger to -# DEBUG. The root logger is the only logger that has a default -# level. Bu default, all other loggers do not have an assigned level, -# such that they inherit their level instead. - -log4j.rootLogger=, A1, A2 - -# A1 is set to be ConsoleAppender sending its output to System.out -log4j.appender.A1=org.apache.log4j.ConsoleAppender - - -# A1 uses PatternLayout. -log4j.appender.A1.layout=org.apache.log4j.PatternLayout - -# The conversion pattern consists of date in ISO8601 format, level, -# thread name, logger name truncated to its rightmost two components -# and left justified to 17 characters, location information consisting -# of file name (padded to 13 characters) and line number, nested -# diagnostic context, the and the application supplied message - -log4j.appender.A1.layout.ConversionPattern=%d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n - -# Appender A2 writes to the file "test". -log4j.appender.A2=org.apache.log4j.FileAppender -log4j.appender.A2.File=test - -# Truncate 'test' if it aleady exists. -log4j.appender.A2.Append=false - -# Appender A2 uses the PatternLayout. -log4j.appender.A2.layout=org.apache.log4j.PatternLayout -log4j.appender.A2.layout.ConversionPattern=%-5r %-5p [%t] %c{2} - %m%n - - -# In this example, we are not interested in INNER loop or SWAP -# messages. You might try to set INNER and SWAP to DEBUG for more -# verbose output. - -log4j.logger.org.apache.log4j.examples.SortAlgo.INNER=INFO -log4j.logger.org.apache.log4j.examples.SortAlgo.SWAP=INFO - diff --git a/examples/src/sort/sort3.properties b/examples/src/sort/sort3.properties deleted file mode 100644 index 8b8e8f2306..0000000000 --- a/examples/src/sort/sort3.properties +++ /dev/null @@ -1,32 +0,0 @@ -# An example log4j configuration file that directs its logging output -# to a SocketAppender. The SocketAppender is configuted to send its -# output to a server running on the localhost port number 12345. - -# To test this example, you must start a log4j server with the command -# -# -# java org.apache.log4j.net.SocketServer 12345 configurationFile directory/ -# -# - -# For the general syntax of property based configuration files see -# the documenation of org.apache.log4j.PropertyConfigurator. - -# The root logger uses the appender called A1. - -log4j.rootLogger=DEBUG, A1 - -# A1 is set to be a SocketAppender sending its output to the server -running on the local host, port 12345. - -log4j.appender.A1=org.apache.log4j.net.SocketAppender -log4j.appender.A1.Port=12345 -log4j.appender.A1.RemoteHost=localhost - -# In this example, we are not interested in INNER loop or SWAP -# messages. You might try to set INNER and SWAP to DEBUG for more -# verbose output. - -log4j.logger.org.apache.log4j.examples.SortAlgo.INNER=INFO -log4j.logger.org.apache.log4j.examples.SortAlgo.SWAP=INFO - diff --git a/examples/src/sort/sort4.properties b/examples/src/sort/sort4.properties deleted file mode 100644 index ecbd6ab02c..0000000000 --- a/examples/src/sort/sort4.properties +++ /dev/null @@ -1,32 +0,0 @@ -# Attach appender A1 to root. Set root level to Level.DEBUG. -log4j.rootLogger=DEBUG, A1 - -# A1 is set to be a FileAppender sending its output to -# System.out. However, only error messages and above will be printed -# in A1 because A1's threshold is set to Level.ERROR. - -# The fact that the root level is set to Prority.DEBUG only influences -# log requests made to the root logger. It has no influence on the -# *appenders* attached to root. - -log4j.appender.A1=org.apache.log4j.ConsoleAppender -log4j.appender.A1.Threshold=ERROR - -log4j.appender.A1.layout=org.apache.log4j.PatternLayout -log4j.appender.A1.layout.ConversionPattern=%p [%t] %c{2} (%M:%L) - %m%n - -# Set the level of the logger named "org.apache.log4j.examples" to -# Level.INFO, attach appender A2. -log4j.logger.org.apache.log4j.examples=INFO, A2 - -# Appender A2 writes to the file "test" in user's home. -log4j.appender.A2=org.apache.log4j.FileAppender -log4j.appender.A2.File=${user.home}/test - -# Truncate 'test' if it aleady exists. -log4j.appender.A2.Append=false - -# Appender A2 uses the PatternLayout. -log4j.appender.A2.layout=org.apache.log4j.PatternLayout -log4j.appender.A2.layout.ConversionPattern=%5r %-5p [%t] %c{2} - %m%n - diff --git a/examples/src/subclass/MyLoggerFactory.java b/examples/src/subclass/MyLoggerFactory.java deleted file mode 100644 index 282b83aa19..0000000000 --- a/examples/src/subclass/MyLoggerFactory.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package subclass; - -import org.apache.log4j.Logger; -import org.apache.log4j.spi.LoggerFactory; - -/** - A factory that makes new {@link MyLogger} objects. - - See source - code for more details. - - @author Ceki Gülcü */ -public class MyLoggerFactory implements LoggerFactory { - - /** - The constructor should be public as it will be called by - configurators in different packages. */ - public - MyLoggerFactory() { - } - - public - Logger makeNewLoggerInstance(String name) { - return new MyLogger(name); - } -} diff --git a/examples/src/subclass/mycat.bad b/examples/src/subclass/mycat.bad deleted file mode 100644 index 570abd1ac2..0000000000 --- a/examples/src/subclass/mycat.bad +++ /dev/null @@ -1,18 +0,0 @@ - -# The usual stuff. Note that A1 is configured in root not in "some.cat" -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 -# 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 - - - diff --git a/examples/src/subclass/mycat.good b/examples/src/subclass/mycat.good deleted file mode 100644 index 469d4c9853..0000000000 --- a/examples/src/subclass/mycat.good +++ /dev/null @@ -1,24 +0,0 @@ -# Setting the logger factory to MyLoggerFactory solves the -# ClassCastException problem encountered with the "mycat.bad" -# configuration file. - -log4j.loggerFactory=examples.subclass.MyLoggerFactory - - -# The usual stuff. Note that A1 is configured in root not in "some.cat" - -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 -# 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.logger.some.cat=TRACE#examples.customLevel.XLevel - diff --git a/examples/src/trivial/Trivial.java b/examples/src/trivial/Trivial.java deleted file mode 100644 index 5e99ad7050..0000000000 --- a/examples/src/trivial/Trivial.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package trivial; - -import org.apache.log4j.BasicConfigurator; -import org.apache.log4j.Logger; -import org.apache.log4j.NDC; - - -/** - View the source code of this a - trivial usage example. Running java examples.Trivial - should output something similar to: - -

-      0    INFO  [main] examples.Trivial (Client #45890) - Awake awake. Put on thy strength.
-      15   DEBUG [main] examples.Trivial (Client #45890 DB) - Now king David was old.
-      278  INFO  [main] examples.Trivial$InnerTrivial (Client #45890) - Entered foo.
-      293  INFO  [main] examples.Trivial (Client #45890) - Exiting Trivial.
-   
- -

The increasing numbers at the beginning of each line are the - times elapsed since the start of the program. The string between - the parentheses is the nested diagnostic context. - -

See {@link Sort} and {@link SortAlgo} for sligtly more elaborate - examples. - -

Note thent class files for the example code is not included in - any of the distributed log4j jar files. You will have to add the - directory /dir-where-you-unpacked-log4j/classes to - your classpath before trying out the examples. - - */ -public class Trivial { - static Logger logger = Logger.getLogger(Trivial.class.getName()); - - public static void main(String[] args) { - BasicConfigurator.configure(); - NDC.push("Client #45890"); - - logger.info("Awake awake. Put on thy strength."); - Trivial.foo(); - InnerTrivial.foo(); - logger.info("Exiting Trivial."); - } - - static void foo() { - NDC.push("DB"); - logger.debug("Now king David was old."); - NDC.pop(); - } - - static class InnerTrivial { - static Logger logger = Logger.getLogger(InnerTrivial.class.getName()); - - static void foo() { - logger.info("Entered foo."); - } - } -} diff --git a/examples/src/subclass/MyLogger.java b/examples/subclass/MyLogger.java similarity index 75% rename from examples/src/subclass/MyLogger.java rename to examples/subclass/MyLogger.java index 1818c5ad9a..d2368b03a2 100644 --- a/examples/src/subclass/MyLogger.java +++ b/examples/subclass/MyLogger.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -14,10 +15,10 @@ * limitations under the License. */ -package subclass; +package examples.subclass; import org.apache.log4j.*; -import customLevel.XLevel; +import examples.customLevel.XLevel; /** A simple example showing logger subclassing. @@ -58,7 +59,9 @@ void debug(Object message) { This method overrides {@link Logger#getLogger} by supplying its own factory type as a parameter. */ - public static Logger getLogger(String name) { + public + static + Logger getLogger(String name) { return Logger.getLogger(name, myFactory); } diff --git a/examples/subclass/MyLoggerFactory.java b/examples/subclass/MyLoggerFactory.java new file mode 100644 index 0000000000..8f859a1121 --- /dev/null +++ b/examples/subclass/MyLoggerFactory.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package examples.subclass; + +import org.apache.log4j.Logger; +import org.apache.log4j.spi.LoggerFactory; + +/** + A factory that makes new {@link MyLogger} objects. + + See source + code for more details. + + @author Ceki Gülcü */ +public class MyLoggerFactory implements LoggerFactory { + + /** + The constructor should be public as it will be called by + configurators in different packages. */ + public + MyLoggerFactory() { + } + + public + Logger makeNewLoggerInstance(String name) { + return new MyLogger(name); + } +} diff --git a/examples/src/subclass/MyLoggerTest.java b/examples/subclass/MyLoggerTest.java similarity index 76% rename from examples/src/subclass/MyLoggerTest.java rename to examples/subclass/MyLoggerTest.java index f744253083..6ea39f5d56 100644 --- a/examples/src/subclass/MyLoggerTest.java +++ b/examples/subclass/MyLoggerTest.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -14,12 +15,12 @@ * limitations under the License. */ -package subclass; +package examples.subclass; import org.apache.log4j.*; - +import org.apache.log4j.xml.DOMConfigurator; import org.apache.log4j.PropertyConfigurator; -import org.apache.log4j.joran.JoranConfigurator; +import org.apache.log4j.helpers.LogLog; /** A simple example showing logger subclassing. @@ -57,10 +58,9 @@ static public void main(String[] args) { } else if(args.length == 1) { if(args[0].endsWith("xml")) { - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure(args[0], LogManager.getLoggerRepository()); + DOMConfigurator.configure(args[0]); } else { - PropertyConfigurator.configure(args[0]); + PropertyConfigurator.configure(args[0]); } } else { usage("Incorrect number of parameters."); @@ -70,8 +70,7 @@ else if(args.length == 1) { c.trace("Hello"); c.debug("Hello"); } catch(ClassCastException e) { - System.err.println("Did you forget to set the factory in the config file?"); - e.printStackTrace(System.err); + LogLog.error("Did you forget to set the factory in the config file?", e); } } diff --git a/examples/tiny-webapp/Hello/.cvsignore b/examples/tiny-webapp/Hello/.cvsignore deleted file mode 100644 index 65c9f761f4..0000000000 --- a/examples/tiny-webapp/Hello/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -build.properties -hello.war diff --git a/examples/tiny-webapp/Hello/README.txt b/examples/tiny-webapp/Hello/README.txt deleted file mode 100644 index 1b82cc1e47..0000000000 --- a/examples/tiny-webapp/Hello/README.txt +++ /dev/null @@ -1,12 +0,0 @@ - -The tiny web-applications Hello and Tata demonstrate how multiple -web-apps can live in separate logging contexts. - -For installation instructions see the file INSTALL.txt in the parent -directory. - -Note that you will need log4j-VERSION.jar to compile the -web-applications but it should not be included in the -web-application's jar file. - - diff --git a/examples/tiny-webapp/Hello/WebRoot/WEB-INF/classes/.cvsignore b/examples/tiny-webapp/Hello/WebRoot/WEB-INF/classes/.cvsignore deleted file mode 100644 index ef03933603..0000000000 --- a/examples/tiny-webapp/Hello/WebRoot/WEB-INF/classes/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -wombat diff --git a/examples/tiny-webapp/Hello/WebRoot/WEB-INF/classes/hello-log4j.xml b/examples/tiny-webapp/Hello/WebRoot/WEB-INF/classes/hello-log4j.xml deleted file mode 100644 index f3102b7e02..0000000000 --- a/examples/tiny-webapp/Hello/WebRoot/WEB-INF/classes/hello-log4j.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/tiny-webapp/Hello/WebRoot/WEB-INF/web.xml b/examples/tiny-webapp/Hello/WebRoot/WEB-INF/web.xml deleted file mode 100644 index 4616008334..0000000000 --- a/examples/tiny-webapp/Hello/WebRoot/WEB-INF/web.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - Hello sample web-application - - - some-init-servlet - wombat.InitServlet - 1 - - - - HelloServlet - wombat.HelloServlet - - - - HelloServlet - /HelloServlet - - - - JNDI logging context for this app - log4j/context-name - hello - java.lang.String - - - - URL for configuring log4j context - log4j/configuration-resource - hello-log4j.xml - java.lang.String - - - - org.apache.log4j.selector.servlet.ContextDetachingSCL - - - diff --git a/examples/tiny-webapp/Hello/WebRoot/index.html b/examples/tiny-webapp/Hello/WebRoot/index.html deleted file mode 100644 index 86151ebf5d..0000000000 --- a/examples/tiny-webapp/Hello/WebRoot/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - -

-Your name: - -
- - - \ No newline at end of file diff --git a/examples/tiny-webapp/Hello/build.properties.sample b/examples/tiny-webapp/Hello/build.properties.sample deleted file mode 100644 index 4880e9917c..0000000000 --- a/examples/tiny-webapp/Hello/build.properties.sample +++ /dev/null @@ -1,10 +0,0 @@ -# Sample build.properties file - -# The path to the web-server home -webserver.home=/java/tomcat/ - -# The deployment target directory on the web server -target.webapp.dir=${webserver.home}/webapps - -# We need servlet to compile the various servlets. -servlet.jar=/java/servlet.jar diff --git a/examples/tiny-webapp/Hello/build.xml b/examples/tiny-webapp/Hello/build.xml deleted file mode 100644 index 6c10f89199..0000000000 --- a/examples/tiny-webapp/Hello/build.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/tiny-webapp/Hello/src/java/wombat/HelloServlet.java b/examples/tiny-webapp/Hello/src/java/wombat/HelloServlet.java deleted file mode 100644 index 675d5e2076..0000000000 --- a/examples/tiny-webapp/Hello/src/java/wombat/HelloServlet.java +++ /dev/null @@ -1,33 +0,0 @@ - -package wombat; - -import java.io.*; -import javax.servlet.*; -import javax.servlet.http.*; -import org.apache.log4j.*; - -public class HelloServlet extends HttpServlet { - - private Logger logger = Logger.getLogger(HelloServlet.class); - - public void init() throws ServletException { - ServletContext context = getServletConfig().getServletContext(); - logger.info("Servlet loaded"); - } - - public void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - - String name = request.getParameter("name"); - - response.setContentType("text/html"); - PrintWriter out = response.getWriter(); - - logger.info("About to say hello to "+name); - - out.println(""); - out.println("

Hello there " + name + ". How are you today?

"); - out.println(""); - out.close(); - } -} diff --git a/examples/tiny-webapp/Hello/src/java/wombat/InitServlet.java b/examples/tiny-webapp/Hello/src/java/wombat/InitServlet.java deleted file mode 100644 index c6d8571010..0000000000 --- a/examples/tiny-webapp/Hello/src/java/wombat/InitServlet.java +++ /dev/null @@ -1,19 +0,0 @@ -package wombat; - -import org.apache.log4j.*; -import org.apache.log4j.spi.RootLogger; -import javax.servlet.http.*; -import javax.servlet.*; - -public class InitServlet extends HttpServlet { - - static Logger logger = Logger.getLogger(InitServlet.class); - public void init() { - logger.info("Logging initialized for Hello."); - } - - public void doGet(HttpServletRequest req, HttpServletResponse res) { - // nothing to do - } -} - diff --git a/examples/tiny-webapp/INSTALL.txt b/examples/tiny-webapp/INSTALL.txt deleted file mode 100644 index dcedbb06ee..0000000000 --- a/examples/tiny-webapp/INSTALL.txt +++ /dev/null @@ -1,161 +0,0 @@ - -The tiny web-applications Hello and Tata demonstrate how multiple -web-apps can live in separate logging contexts. - -Here are the installation steps to run the examples. - -Steps performed on the Java Web Server (Servlet Container) -========================================================= - -- Place log4j-VERSION.jar, where VERSION is 1.3 or above, in your web - server's (YES, server's) shared class directory. - - For example, for Tomcat versions 4 or 5, that would be ./common/lib/ - under the Tomcat installation folder, for Resin version 2.1.x that - would be the ./lib/ directory under the Resin installation folder. - Other Servlet containers such as Jetty also have folders for - shared jar files. - -- On the java command line launching your java web *server*, make sure - to add te log4j.repositorySelector system property. For the - JNDIContextSelector the exact system property to add is: - - -Dlog4j.repositorySelector=org.apache.log4j.selector.ContextJNDISelector - - or in its equivalent but shorter form - - -Dlog4j.repositorySelector=JNDI - - For Tomcat, you can add this line directly in ./bin/catalina.sh or - ./bin/catalina.bat. - - After you start Tomcat, the $TOMCAT_HOME/logs/catalina.out file - should contain a line with the following text. - - *** Will use ContextJNDISelector ** - - If the above line exists, then you can be certain that setting the - log4j.repositorySelector system property had the desired affect. - -- You can now run the supplied web-applications hello.war and - tata.war. - - Alternatively, you can instruct Tomcat to run Hello and Tata - directly form LOG4J_HOME. Here is an excerpt from our 'server.xml' - file, that is Tomcat's configration file. - - - - - - - - - -- Optionally, you can add a configuration file such as log4j.xml or - log4j.properties in the class directory of your *web-server*. For - Tomcat versions 4 or 5, that would be ./common/classes/ directory. - - Thus, when log4j is first loaded into memory, it will configure the - default logging repository using the configuration file found in - ./common/classes/ directory. - -- Instructing Tomcat to use log4j - - If you would like Tomcat to use log4j and its default repository, - you also need to tell Tomcat to use log4j by placing - commons-logging.jar in ./common/lib directory. - - This way the default (log4j) logger repository will be used by - Tomcat for its logging and the default logger repository will be - controlled by the configuration file log4j.xml or log4j.properties - found in ./common/classes/. (Tested on Tomcat 5.0.19 and 5.0.27), - -Steps performed per web-application -================================== - -- You will need log4j-VERSION.jar to compile the - web-applications. However, log4j-VERSION.jar file need not and - should not be included within the web-application's WAR file. - -- In each web-application's web.ml file add a JNDI environment entry - for the log4j logging context name. For the "Hello" web-application - this takes the following form: - - - JNDI logging context for this app - log4j/context-name - hello - java.lang.String - - - See also the file examples/tiny-webapp/Hello/src/WEB-INF/web.xml - -- Specify the URL for this context's configuration resource using - the "log4j/configuration-resource" environment entry. - The repository selector (ContextJNDISelector) will use the - specified resource to configure the log4j repository. - - - URL for configuring log4j context - log4j/configuration-resource - urlOfConfigrationResource - java.lang.String - - - Note if the "log4j/configuration-resource" environment entry - is missing, then the logger repository for your application's logging - context will NOT be configured. - - For more information on the available options see the javadoc for - org.apache.log4j.selector.ContextJNDISelector. - -- When the web-application is recycled or shutdown, it is very often useful - to recycle the associated logging repository. This can be done by - installing a ServletContextListener which will detach the repository - from the repository selector and shut it down. - - The ContextDetachingSCL, where SCL stands ServletContextListener, which - ships with log4j does exactly that. To install it, add the following - lines to your web-application's web.xml file. - - - org.apache.log4j.selector.servlet.ContextDetachingSCL - - - See also the file examples/tiny-webapp/Hello/src/WEB-INF/web.xml - -- You are also encouraged to name your web-application in the web - descriptor file. As in - - Hello sample web-application - - -CAVEAT -====== - -We recommend that you name log4j configuration resources uniquely. In -particualar, avoid naming the log4j configuration resource as -'log4j.xml' or as 'log4j.properties' for a non-default logger -repository. For example, the following env-entry is error-prone: - - - URL for configuring log4j context - log4j/configuration-resource - log4j.xml - java.lang.String - - -While trying to configure the web-application log4j would search for -the resource 'log4j.xml' using the thread context classloader. Thus, -it would first attempt to locate 'log4j.xml' file using the -classloader specific to the web-application. However, if the file -'log4j.xml' did not exist there (if you forgot to put a custom one in -WEB-INF/classes), and if the file 'log4j.xml' existed higher up in the -classloader tree, we could end up in a situation where the logger -repository for your web-application would be configured using the same -file as that used to configure the default repository. Such -involuntary sharing of the same configuration by multiple repositories -will result in corrupt log output. diff --git a/examples/tiny-webapp/Tata/.cvsignore b/examples/tiny-webapp/Tata/.cvsignore deleted file mode 100644 index 1897fee99f..0000000000 --- a/examples/tiny-webapp/Tata/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -classes -build.properties -tata.war \ No newline at end of file diff --git a/examples/tiny-webapp/Tata/README.txt b/examples/tiny-webapp/Tata/README.txt deleted file mode 100644 index 1b82cc1e47..0000000000 --- a/examples/tiny-webapp/Tata/README.txt +++ /dev/null @@ -1,12 +0,0 @@ - -The tiny web-applications Hello and Tata demonstrate how multiple -web-apps can live in separate logging contexts. - -For installation instructions see the file INSTALL.txt in the parent -directory. - -Note that you will need log4j-VERSION.jar to compile the -web-applications but it should not be included in the -web-application's jar file. - - diff --git a/examples/tiny-webapp/Tata/WebRoot/WEB-INF/classes/.cvsignore b/examples/tiny-webapp/Tata/WebRoot/WEB-INF/classes/.cvsignore deleted file mode 100644 index ef03933603..0000000000 --- a/examples/tiny-webapp/Tata/WebRoot/WEB-INF/classes/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -wombat diff --git a/examples/tiny-webapp/Tata/WebRoot/WEB-INF/classes/tata-log4j.xml b/examples/tiny-webapp/Tata/WebRoot/WEB-INF/classes/tata-log4j.xml deleted file mode 100644 index ca021c6571..0000000000 --- a/examples/tiny-webapp/Tata/WebRoot/WEB-INF/classes/tata-log4j.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/examples/tiny-webapp/Tata/WebRoot/WEB-INF/web.xml b/examples/tiny-webapp/Tata/WebRoot/WEB-INF/web.xml deleted file mode 100644 index d6eb3cfbec..0000000000 --- a/examples/tiny-webapp/Tata/WebRoot/WEB-INF/web.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - some-init-servlet - wombat.InitServlet - 1 - - - - - TataServlet - wombat.TataServlet - - - - TataServlet - /TataServlet - - - - JNDI logging context for this app - log4j/context-name - tata - java.lang.String - - - - URL for configuring log4j context - log4j/configuration-resource - tata-log4j.xml - java.lang.String - - - - - org.apache.log4j.selector.servlet.ContextDetachingSCL - - - diff --git a/examples/tiny-webapp/Tata/WebRoot/index.html b/examples/tiny-webapp/Tata/WebRoot/index.html deleted file mode 100644 index 4285c4d970..0000000000 --- a/examples/tiny-webapp/Tata/WebRoot/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - -
-Enter your name: - -
- - - \ No newline at end of file diff --git a/examples/tiny-webapp/Tata/build.properties.sample b/examples/tiny-webapp/Tata/build.properties.sample deleted file mode 100644 index 67b2d1b7cb..0000000000 --- a/examples/tiny-webapp/Tata/build.properties.sample +++ /dev/null @@ -1,14 +0,0 @@ -# Sample build.properties file - -# The path to the web-server home -webserver.home=/java/tomcat/ - -# The deployment target directory on the web server -target.webapp.dir=${webserver.home}/webapps - -# We need servlet to compile the various servlets. -servlet.jar=/java/servlet.jar - - -# We need log4j-x.jar to run these examples -log4j.jar=../../../log4j-1.3alpha.jar diff --git a/examples/tiny-webapp/Tata/build.xml b/examples/tiny-webapp/Tata/build.xml deleted file mode 100644 index 683a9a927c..0000000000 --- a/examples/tiny-webapp/Tata/build.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/tiny-webapp/Tata/src/java/wombat/InitServlet.java b/examples/tiny-webapp/Tata/src/java/wombat/InitServlet.java deleted file mode 100644 index 6f78253ac6..0000000000 --- a/examples/tiny-webapp/Tata/src/java/wombat/InitServlet.java +++ /dev/null @@ -1,19 +0,0 @@ -package wombat; - -import org.apache.log4j.*; -import org.apache.log4j.spi.RootLogger; -import javax.servlet.http.*; -import javax.servlet.*; - -public class InitServlet extends HttpServlet { - - static Logger logger = Logger.getLogger(InitServlet.class); - public void init() { - logger.info("Logging initialized for Tata."); - } - - public void doGet(HttpServletRequest req, HttpServletResponse res) { - // nothing to do - } -} - diff --git a/examples/tiny-webapp/Tata/src/java/wombat/TataServlet.java b/examples/tiny-webapp/Tata/src/java/wombat/TataServlet.java deleted file mode 100644 index 0bda18d66a..0000000000 --- a/examples/tiny-webapp/Tata/src/java/wombat/TataServlet.java +++ /dev/null @@ -1,33 +0,0 @@ - -package wombat; - -import java.io.*; -import javax.servlet.*; -import javax.servlet.http.*; -import org.apache.log4j.*; - -public class TataServlet extends HttpServlet { - - private Logger logger = Logger.getLogger(TataServlet.class); - - public void init() throws ServletException { - ServletContext context = getServletConfig().getServletContext(); - logger.info("Servlet loaded"); - } - - public void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - - String name = request.getParameter("name"); - - response.setContentType("text/html"); - PrintWriter out = response.getWriter(); - - logger.info("About to say Tata to "+name); - - out.println(""); - out.println("

Many tata's to you " + name + ". How are you today?

"); - out.println(""); - out.close(); - } -} diff --git a/packaging/.functions b/packaging/.functions deleted file mode 100644 index fe8eff28f0..0000000000 --- a/packaging/.functions +++ /dev/null @@ -1,40 +0,0 @@ -# +=============================================+ -# Strip the filename, retain the directory only.| -# +=============================================+ -function getShellScriptDirectory { - local dir - - dir=${0%/*} - - if [ "$dir" = "." ] - then - dir=$(pwd) - elif [ "${dir#/}" = "$dir" ] # dir does not start with a / - then - dir=$(pwd)/$dir - fi - echo $dir -} -# ============================================== -# Delete the file if exists -# ============================================== -function deleteFile { - if [ -e $1 ]; then - echo "Deleting file [$1]." - rm $1 - fi -} -# ============================================== -# Change extension of file if it exists -# ============================================== -function changeFileExtension { - filename=$1 - ext=$2 - #echo "File mame =$1, ext=$2" - if [ -e $filename ]; then - noext=${filename%.*} - echo "Renaming [$filename] to [$noext.$ext]." - mv $filename $noext.$ext - fi -} -# ============================================== diff --git a/packaging/install b/packaging/install deleted file mode 100644 index 41d1ae82f5..0000000000 --- a/packaging/install +++ /dev/null @@ -1,189 +0,0 @@ -#!/bin/bash - -# Usage: install [-j] [-h] -# -j: jar files only -# -h: do not update the history file - -# +=============================================+ -# Strip the filename, retain the directory only.| -# +=============================================+ -function getShellScriptDirectory { - local dir - - dir=${0%/*} - - if [ "$dir" = "." ] - then - dir=$(pwd) - elif [ "${dir#/}" = "$dir" ] # dir does not start with a / - then - dir=$(pwd)/$dir - fi - echo $dir -} -# ================================================== - -WWW_TARGET=~/ASF/dump -DISTRIB_TARGET=~/sf/temp -JAR_FULL=log4j.jar -JAR_CORE=log4j-core.jar - - -if [ -z "$ANT" ] -then - ANT=ant -fi - - -while getopts ":jh" opt; do - - case $opt in - j ) JAR_ONLY=true - ;; - h ) NO_HISTORY=true - ;; - \? ) echo "Usage: install [-j] [-h]" - echo " -j: jar files only" - echo " -h: do not update the history file" - exit; - esac -done - -# ================================================================= -function cleanUp { - echo "" -} -# ================================================================= - -pushd $PWD > /dev/null - -scriptDir=$(getShellScriptDirectory) -echo "Script directry is determined to be [$scriptDir]" - -echo "Sourcing ${scriptDir}/.functions" -. ${scriptDir}/.functions - -echo "Setting current dir to [${scriptDir}/..]" -cd ${scriptDir}/.. -PKG_DIR=$PWD - -# ${PKG_DIR##*/} returns the package name -PKG_NAME=${PKG_DIR##*/} - -# Package name is [$PKG_NAME] - -TGZ_FILE=${PKG_NAME}.tgz -ZIP_FILE=${PKG_NAME}.zip - -echo "Deleting \"core\" files." -find . -type f -name core -exec rm {} \; - -deleteFile $PKG_DIR/org/apache/log4j/performance/test -deleteFile $PKG_DIR/org/apache/log4j/test/temp -deleteFile $PKG_DIR/org/apache/log4j/test/temp.A1 -deleteFile $PKG_DIR/org/apache/log4j/test/temp.A2 -deleteFile $PKG_DIR/org/apache/log4j/test/temp.x -deleteFile $PKG_DIR/org/apache/log4j/test/temp.1 -deleteFile $PKG_DIR/org/apache/log4j/test/temp.2 -deleteFile $PKG_DIR/org/apache/log4j/test/temp.3 -deleteFile $PKG_DIR/org/apache/log4j/test/logging.lcf -deleteFile $PKG_DIR/org/apache/log4j/test/logging.cat -deleteFile $PKG_DIR/org/apache/log4j/test/current.reg -deleteFile $PKG_DIR/org/apache/log4j/test/current.reg.A1 -deleteFile $PKG_DIR/org/apache/log4j/test/current.reg.A2 -deleteFile $PKG_DIR/org/apache/log4j/test/log4j.properties -deleteFile $PKG_DIR/org/apache/log4j/test/socket.lcf -deleteFile $PKG_DIR/org/apache/log4j/test/file -deleteFile $PKG_DIR/org/apache/log4j/test/output.A1 - -deleteFile $PKG_DIR/org/apache/log4j/examples/test -deleteFile $PKG_DIR/org/apache/log4j/xml/test/output.A1 -deleteFile $PKG_DIR/org/apache/log4j/xml/test/output.A2 -deleteFile $PKG_DIR/org/apache/log4j/xml/test/temp.A1 -deleteFile $PKG_DIR/org/apache/log4j/xml/test/temp.A2 -deleteFile $PKG_DIR/org/apache/log4j/xml/test/current.reg -deleteFile $PKG_DIR/org/apache/log4j/nt/EventLogCategories.dbg -deleteFile $PKG_DIR/org/apache/log4j/nt/EventLogCategories.h -deleteFile $PKG_DIR/org/apache/log4j/nt/EventLogCategories.rc -deleteFile $PKG_DIR/org/apache/log4j/nt/EventLogCategories.RES -deleteFile $PKG_DIR/org/apache/log4j/nt/MSG00001.bin -deleteFile $PKG_DIR/org/apache/log4j/nt/NTEventLogAppender.lib -deleteFile $PKG_DIR/org/apache/log4j/nt/NTEventLogAppender.exp -deleteFile $PKG_DIR/org/apache/log4j/nt/vc50.idb -deleteFile $PKG_DIR/org/apache/log4j/net/test/loop.log -deleteFile $PKG_DIR/org/apache/log4j/net/test/loop.log.1 -deleteFile $PKG_DIR/classes/org/apache/log4j/UnitTestCategory.class -deleteFile $PKG_DIR/org/apache/log4j/varia/test/temp -deleteFile $PKG_DIR/org/apache/log4j/xml/test/temp - -echo "Cleaning \"classes\" directory." -find . -type d -path "./classes/exercise" -exec rm -r {} \; -find . -type d -path "./classes/make" -exec rm -r {} \; - -echo -n "Build stamp: " -date -u +"%Y-%m-%d %T %Z" - -echo "About to run ANT. Current directory is [$PWD]" -$ANT jar - -if [ "$?" != "0" ]; then - echo "jar failed! Exiting."; popd; exit 1 -fi - -if [ -n "$JAR_ONLY" ]; then - cleanUp - exit -fi - - - -# Run tramake -$scriptDir/tarmake - -if [ "$?" != "0" ]; then - echo "There was an error while running \"$scriptDir/tarmake\". Exiting." - exit 1 -fi - -if [ ! -s ../$TGZ_FILE ] -then - echo "../$TGZ_FILE does not exists in $PWD/.." - exit 1 -fi - - -echo "Moving $TGZ_FILE to $WWW_TARGET/" -mv ../$TGZ_FILE $WWW_TARGET/ -if [ "$?" != "0" ]; then - echo "There was an error moving ../$TGZ_FILE to $WWW_TARGET/" - exit 1 -fi - -echo "About to do ZIP processing in [$DISTRIB_TARGET]" - -# Clean up old copy of package in $DISTRIB_TARGET -cd $DISTRIB_TARGET -if [ -d $DISTRIB_TARGET/$PKG_NAME ]; then - echo; echo "Removing directory $DISTRIB_TARGET/$PKG_NAME" - rm -r $DISTRIB_TARGET/$PKG_NAME - if [ "$?" != "0" ]; then - echo "Could not remove $DISTRIB_TARGET/$PKG_NAME. Exiting."; exit 1 - fi -fi - -echo; echo "Untarring $WWW_TARGET/$TGZ_FILE in $PWD" -tar xzf $WWW_TARGET/$TGZ_FILE - -cd $DISTRIB_TARGET -echo; -if [ -e $WWW_TARGET/$ZIP_FILE ]; then - echo "Removing stale $WWW_TARGET/$ZIP_FILE" - rm $WWW_TARGET/$ZIP_FILE -fi -echo "Zipping $PKG_NAME in $DISTRIB_TARGET to $WWW_TARGET/$ZIP_FILE" -zip -y -9 -q -r $WWW_TARGET/$ZIP_FILE $PKG_NAME -if [ "$?" != "0" ]; then - echo "There was an error while zipping. Exiting."; exit 1 -fi - -cleanUp diff --git a/packaging/package-list b/packaging/package-list deleted file mode 100644 index 407d0d79a5..0000000000 --- a/packaging/package-list +++ /dev/null @@ -1,59 +0,0 @@ -java.applet -java.awt -java.awt.color -java.awt.datatransfer -java.awt.dnd -java.awt.event -java.awt.font -java.awt.geom -java.awt.im -java.awt.image -java.awt.image.renderable -java.awt.print -java.beans -java.beans.beancontext -java.io -java.lang -java.lang.ref -java.lang.reflect -java.math -java.net -java.rmi -java.rmi.activation -java.rmi.dgc -java.rmi.registry -java.rmi.server -java.security -java.security.acl -java.security.cert -java.security.interfaces -java.security.spec -java.sql -java.text -java.util -java.util.jar -java.util.zip -javax.accessibility -javax.swing -javax.swing.border -javax.swing.colorchooser -javax.swing.event -javax.swing.filechooser -javax.swing.plaf -javax.swing.plaf.basic -javax.swing.plaf.metal -javax.swing.plaf.multi -javax.swing.table -javax.swing.text -javax.swing.text.html -javax.swing.text.html.parser -javax.swing.text.rtf -javax.swing.tree -javax.swing.undo -org.omg.CORBA -org.omg.CORBA.DynAnyPackage -org.omg.CORBA.ORBPackage -org.omg.CORBA.portable -org.omg.CORBA.TypeCodePackage -org.omg.CosNaming -org.omg.CosNaming.NamingContextPackage diff --git a/packaging/tarmake b/packaging/tarmake deleted file mode 100644 index 39e6abf5de..0000000000 --- a/packaging/tarmake +++ /dev/null @@ -1,72 +0,0 @@ -# use v as argument for verbose tar output - -# Note: the ${pkg}.tgz file is output in $scriptDir/../.. - -#. .functions > /dev/null - -pushd $PWD > /dev/null - -scriptDir=$(getShellScriptDirectory) -echo "tarmake script directory found to be [$scriptDir]." - -tmp0=${scriptDir%/packaging} -pkg=${tmp0##/*/} -echo "Package version name found to be [$pkg]." - -cd $scriptDir/../.. - -echo "tarmake current directory is [$PWD]" - -if [ ! -s $pkg/packaging/package-list ] -then - echo "Could not find file \"package-list\" in directory $pkg/packaging." - echo "Current direcotry is [$PWD]." - exit 1 -fi - - -echo;echo "Making tar file $pkg.tgz in $PWD" -find $pkg -name "*CVS*" -o -name ".#*" -o -name "*~" -o -name \ - "*util.old*" -o -name "*misc*" -o -name TAGS -o -name "*.avaj" \ - -o -name make.loc -o -name "*pending*"\ - -o -path "*nt/Readme.txt" -o -name goEtags -o -name "JListView*" \ - -o -name "JTableAppender*" > $scriptDir/tar-exclude - -if [ $? -ne 0 ]; then - echo "Find failed with exit code $?."; exit 1; -fi -tar -cz${1}f ${pkg}.tgz -X $scriptDir/tar-exclude \ - $pkg/make/\ - $pkg/doc/\ - $pkg/xdocs/\ - $pkg/Makefile\ - $pkg/build.xml\ - $pkg/build.inc\ - $pkg/manifest.mf\ - $pkg/INSTALL\ - $pkg/LICENSE.APL\ - $pkg/*.jar\ - $pkg/org/ \ - $pkg/icons\ - $pkg/classes/ \ - $pkg/javadoc/ \ - $pkg/packaging/package-list \ - $pkg/packaging/.functions \ - $pkg/packaging/initialize \ - $pkg/packaging/install \ - $pkg/packaging/tarmake \ - - -if [ $? -ne 0 ]; then - echo "tar failed with exit code $?."; exit 1; -fi - -popd > /dev/null - -echo "tarmake successful." -exit 0 - - - - - diff --git a/pom.xml b/pom.xml old mode 100755 new mode 100644 index 303c8edbb9..cfacd832ff --- a/pom.xml +++ b/pom.xml @@ -15,47 +15,59 @@ limitations under the License. --> - + + 4.0.0 log4j log4j - jar + bundle Apache Log4j - 1.3alpha9-SNAPSHOT - Apache Log4j 1.3 - http://logging.apache.org:80/log4j/1.3/ + 1.2.18-SNAPSHOT + Apache Log4j 1.2 + http://logging.apache.org/log4j/1.2/ - Bugzilla - http://issues.apache.org/bugzilla/ + Bugzilla + https://issues.apache.org/bugzilla/describecomponents.cgi?product=Log4j - Gump - http://vmgump.apache.org/gump/public/logging-log4j/logging-log4j/index.html - + Gump + http://vmgump.apache.org/gump/public/logging-log4j-12/logging-log4j-12/index.html + 1999 - - log4j-user - log4j-user-subscribe@logging.apache.org - log4j-user-unsubscribe@logging.apache.org - log4j-user@logging.apache.org - http://mail-archives.apache.org/mod_mbox/logging-log4j-dev/ - - http://marc.info/?l=log4j-user - http://dir.gmane.org/gmane.comp.jakarta.log4j.user - - - - log4j-dev - log4j-dev-subscribe@logging.apache.org - log4j-dev-unsubscribe@logging.apache.org - log4j-dev@logging.apache.org - http://mail-archives.apache.org/mod_mbox/logging-log4j-dev/ - - http://marc.info/?l=log4j-dev - http://dir.gmane.org/gmane.comp.jakarta.log4j.devel - - + + log4j-user + log4j-user-subscribe@logging.apache.org + log4j-user-unsubscribe@logging.apache.org + log4j-user@logging.apache.org + http://mail-archives.apache.org/mod_mbox/logging-log4j-user/ + + http://marc.info/?l=log4j-user + http://dir.gmane.org/gmane.comp.jakarta.log4j.user + + + + log4j-dev + log4j-dev-subscribe@logging.apache.org + log4j-dev-unsubscribe@logging.apache.org + log4j-dev@logging.apache.org + http://mail-archives.apache.org/mod_mbox/logging-log4j-dev/ + + http://marc.info/?l=log4j-dev + http://dir.gmane.org/gmane.comp.jakarta.log4j.devel + + @@ -65,9 +77,9 @@ - scm:svn:http://svn.apache.org/repos/asf/logging/log4j/branches/BRANCH_1_3_ABANDONED - scm:svn:https://svn.apache.org/repos/asf/logging/log4j/branches/BRANCH_1_3_ABANDONED - http://svn.apache.org/viewcvs.cgi/logging/log4j/branches/BRANCH_1_3_ABANDONED + scm:svn:http://svn.apache.org/repos/asf/logging/log4j/trunk + scm:svn:https://svn.apache.org/repos/asf/logging/log4j/trunk + http://svn.apache.org/viewvc/logging/log4j/trunk Apache Software Foundation @@ -75,113 +87,131 @@ + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + maven-surefire-plugin + 2.5 tests plain - pertest - true - - org/apache/log4j/LevelTest.java - org/apache/log4j/PriorityTest.java - org/apache/log4j/CategoryTest.java - org/apache/log4j/FileAppenderTest.java - org/apache/log4j/LogManagerTest.java - org/apache/log4j/helpers.LogLogTest.java - org/apache/log4j/LayoutTest.java - org/apache/log4j/helpers.DateLayoutTest.java - org/apache/log4j/TTCCLayoutTest.java - org/apache/log4j/xml.XMLLayoutTest.java - org/apache/log4j/HTMLLayoutTest.java - org/apache/log4j/PatternLayoutTest.java - org/apache/log4j/spi.LoggingEventTest.java - org/apache/log4j/spi.ThrowableInformationTest.java - org/apache/log4j/spi.LocationInfoTest.java - org/apache/log4j/PropertyConfiguratorTest.java - org/apache/log4j/MinimumTestCase.java - org/apache/log4j/LoggerTestCase.java - org/apache/log4j/PatternLayoutTestCase.java - org/apache/log4j/HierarchyThresholdTestCase.java - org/apache/log4j/xml/DOMTestCase.java - org/apache/log4j/xml/CustomLevelTestCase.java - org/apache/log4j/customLogger/XLoggerTestCase.java - - - org/apache/log4j/xml/XMLLayoutTestCase.java - org/apache/log4j/xml/AsyncAppenderTestCase.java - org/apache/log4j/varia/LevelMatchFilterTestCase.java - - - - org/apache/log4j/helpers/BoundedFIFOTestCase.java - org/apache/log4j/helpers/CyclicBufferTestCase.java - org/apache/log4j/helpers/PatternParserTestCase.java - org/apache/log4j/or/ORTestCase.java - org/apache/log4j/DRFATestCase.java - org/apache/log4j/RFATestCase.java - org/apache/log4j/varia/ERFATestCase.java - org/apache/log4j/net/SyslogAppenderTest - org/apache/log4j/nt/NTEventLogAppenderTest - org/apache/log4j/net/SocketAppenderTest - + pertest + false + + org/apache/log4j/LevelTest.java + org/apache/log4j/PriorityTest.java + org/apache/log4j/CategoryTest.java + org/apache/log4j/FileAppenderTest.java + org/apache/log4j/LogManagerTest.java + org/apache/log4j/helpers.LogLogTest.java + org/apache/log4j/LayoutTest.java + org/apache/log4j/helpers.DateLayoutTest.java + org/apache/log4j/TTCCLayoutTest.java + org/apache/log4j/xml.XMLLayoutTest.java + org/apache/log4j/HTMLLayoutTest.java + org/apache/log4j/PatternLayoutTest.java + org/apache/log4j/spi.LoggingEventTest.java + org/apache/log4j/spi.ThrowableInformationTest.java + org/apache/log4j/spi.LocationInfoTest.java + org/apache/log4j/PropertyConfiguratorTest.java + org/apache/log4j/MinimumTestCase.java + org/apache/log4j/LoggerTestCase.java + org/apache/log4j/PatternLayoutTestCase.java + org/apache/log4j/HierarchyThresholdTestCase.java + org/apache/log4j/xml/DOMTestCase.java + org/apache/log4j/xml/CustomLevelTestCase.java + org/apache/log4j/customLogger/XLoggerTestCase.java + + + org/apache/log4j/xml/XMLLayoutTestCase.java + org/apache/log4j/xml/AsyncAppenderTestCase.java + org/apache/log4j/varia/LevelMatchFilterTestCase.java + + + org/apache/log4j/helpers/BoundedFIFOTestCase.java + org/apache/log4j/helpers/CyclicBufferTestCase.java + org/apache/log4j/helpers/PatternParserTestCase.java + org/apache/log4j/or/ORTestCase.java + org/apache/log4j/DRFATestCase.java + org/apache/log4j/RFATestCase.java + org/apache/log4j/varia/ERFATestCase.java + org/apache/log4j/net/SyslogAppenderTest + org/apache/log4j/nt/NTEventLogAppenderTest + org/apache/log4j/net/SocketAppenderTest + maven-compiler-plugin + 2.1 - 1.2 - 1.1 + 1.4 + 1.4 + UTF-8 - + maven-jar-plugin + 2.3 - - - org.apache.log4j - - log4j - ${project.version} - "Apache Software Foundation" - - - + + + org/apache/log4j/ + + * + log4j + ${project.version} + "Apache Software Foundation" + + + maven-antrun-plugin + 1.2 - + process-classes - ntdll + ntdll - - - - - - - + + + + + + + run - + + + --> + site untag-site - - - + + + - - - + + + run + + + + + + + + javadoc.resources + generate-sources + + run + + + + + + + + + + + + - + ant ant-nodeps @@ -278,167 +338,151 @@ ant-junit 1.6.5 - - junit - junit - 3.8.1 + + junit + junit + 3.8.1 + compile + + + sun.jdk + tools + 1.4.2 + system + ${tools.jar} - - sun.jdk - tools - 1.4.2 - system - ${tools.jar} - - - - maven-assembly-plugin - - - src/assembly/bin.xml - - false + + + maven-assembly-plugin + 2.2-beta-5 + + + src/assembly/bin.xml + + false - - - assembly - - + + + assembly + + - + + maven-javadoc-plugin + 2.7 + + true + .svn + UTF-8 + UTF-8 + - - - jar - javadoc - - + + + jar + javadoc + + + + site + pre-site + + javadoc + + + + maven-release-plugin + 2.0-beta-9 + + + package site-deploy assembly:attached deploy + + maven-source-plugin + 2.1.1 - - - jar - - + + + jar + + - - + + + + org.codehaus.mojo + clirr-maven-plugin + 2.2.2 + + 1.2.15 + + - org.codehaus.mojo - clirr-maven-plugin - - 1.2.14 - + org.codehaus.mojo + rat-maven-plugin + 1.0-alpha-3 + + + tests/witness/** + tests/output/** + tests/classes/** + + - + + org.apache.felix + maven-bundle-plugin + 2.1.0 + true + + + org.apache.log4j + org.apache.log4j.*;version=${project.version};-noimport:=true + + javax.jmdns.*;resolution:=optional, + javax.jms.*;resolution:=optional, + javax.mail.*;resolution:=optional, + * + + http://logging.apache.org/log4j/1.2 + registered + J2SE-1.4 + + + + + maven-site-plugin + 3.1 + + + package + + site + + + + + tests/src/java - - - tests/resources - - - - - - mac - - mac - - - ${java.home}/../Classes/classes.jar - - - - default - - true - - - ${java.home}/../lib/tools.jar - - - - - - java.net - https://maven-repository.dev.java.net/nonav/repository - legacy - - - - - javax.mail - mail - 1.4 - - - javax.jms - jms - 1.1 - - - javax.servlet - servlet-api - 2.5 - - - com.sun.jdmk - jmxtools - 1.2.1 - - - com.sun.jmx - jmxri - 1.2.1 - - - oro - oro - 2.0.8 - - - junit - junit - 3.8.1 - test - - - jetty - org.mortbay.jetty.plus - 4.2.25 - test - - - jetty - jetty - 4.2.12 - test - - - javax.activation - activation - 1.1 - test - - + + + tests/resources + + + - true maven-project-info-reports-plugin + 2.4 @@ -453,31 +497,92 @@ - org.codehaus.mojo - jxr-maven-plugin - - - maven-release-plugin - - site-deploy - + maven-jxr-plugin + 2.1 maven-changes-plugin - + 2.7 + changes-report - - %URL%/show_bug.cgi?id=%ISSUE% - - + - + + + mac + + + mac + + + + ${java.home}/../Classes/classes.jar + ${user.home}/.m2/repository + build + + + + default + + true + + + ${java.home}/../lib/tools.jar + ${user.home}/.m2/repository + build + + + + + + maven2-repository.dev.java.net + Java.net Repository for Maven + http://download.java.net/maven/2/ + default + + + + + javax.mail + mail + 1.4.3 + true + + + org.apache.openejb + javaee-api + 5.0-2 + jar + provided + + + + oro + oro + 2.0.8 + test + + + junit + junit + 3.8.2 + test + + + org.apache.geronimo.specs + geronimo-jms_1.1_spec + 1.0 + true + + + logging.repo scp://people.apache.org/www/people.apache.org/builds/logging/repo/ @@ -486,5 +591,6 @@ logging.site scp://localhost/${user.dir}/target/site-deploy - + + diff --git a/src/assembly/bin.xml b/src/assembly/bin.xml index 4090576ec1..e0d085f516 100644 --- a/src/assembly/bin.xml +++ b/src/assembly/bin.xml @@ -33,18 +33,18 @@ KEYS LICENSE NOTICE - contribs/** + contribs/** examples/** src/assembly/** src/changes/** src/main/** - src/ntdll/** + src/ntdll/* src/performance/** src/site/** - tests/README - tests/*.xml - tests/*.sample - tests/*.bat + tests/README + tests/*.xml + tests/*.sample + tests/*.bat tests/input/** tests/resources/** tests/src/** @@ -60,5 +60,9 @@ target/NTEventLogAppender.dll 0755 + + NTEventLogAppender.amd64.dll + 0755 + diff --git a/src/changes/changes.xml b/src/changes/changes.xml index ed36911849..3c05b302f0 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -1 +1,1888 @@ - log4j Release history Mark Womack Uploaded documentation on how to use the plugin. Added additional documentation on how to configure the plugin. Enable retrieving component-specific issues The element type " link " must be terminated by the matching end-tag. Deleted the erroneous code. \ No newline at end of file + + + + Apache log4j 1.2 + + + + Merged truncate feature to FormattingInfo from extras + Typo in log4j 1.2 manual + Simplify log4j build + MANIFEST.MF broken in log4j-1.2.15.jar + Additional OSGI/BND configuration elements + Ant is not longer supported as build tool + Made use of Mavens Fludio Skin + Log4j site should have some mention of git mirroring + Prepare smaller jar omitting LF5 and Chainsaw 1 + [PATCH] PropertyConfigurator javadoc fixes. + Inheritance spelled "inheritence" in documentation. + Misspelled words in FAQ. + Fix one BZ number in Changelog of 1.2.16. + Missing comma in class header Javadoc for Level. + Log4J SyslogAppender does not handle the TAG field. + + + + log4j 1.2.17 release preparation + Configure from an InputStream + JDBCAppender not closed due to SQL Exception while executing an SQL (thanks to Anurag Agarwal) + Memoryleak - org.apache.log4j.helpers.ThreadLocalMap + DOMConfigurator does not close input stream when configured based on URL. + javadoc.jar was missing NOTICE and LICENSE and contained .svn entries. + Wrong log levels logged with serialized LoggingEvent. + Add org.apache.log4j.rewrite.RewriteAppender and org.apache.log4j.util.UtilLoggingLevel from discontinued receivers companion. + + + + log4j 1.2.16 release preparation. + Create a public identifier for log4j.dtd ("-//APACHE//DTD LOG4J 1.2//EN") + TelnetAppender misses messages when one of many clients disconnect. + TelnetAppender throws null pointers at log time when socket couldn't be opened. + ThrowableInformation.getThrowableStringRep can return null strings. + log4j.dtd defines class attribute for category element, but not for logger. + SMTPAppender.setSMTPUserName and others missing @since tags. + Request for compile-on-Windows help file in src package. + AsyncAppender failing on changing message objects. + Subst-mechanism in DOMConfigurator broken. + DailyRollingFileAppender may lose messages during failed rollover attempts. + Fix mangled source-repository.html. + Minor documentation changes. + Make javamail, jmx, jms dependencies optional in pom.xml. + SocketHubAppender should expose actual port in use to extending classes. + SocketHubAppender in the 1.2.16 does not support a scroll back buffer or application property + Give log4j threads reasonable names. + LocationInfo can report wrong caller when other class names contain logger class name as substring. + ErrorHandlerTestCase is not run and does not pass. + Agent.java is sole dependency on jmxtools.jar with Java 5+. + Eliminate compile dependency on non-redistributable JMS reference implementation. + Exception in call to toString of message propagates to caller. + Javadoc class index corrupted by JDBCAppender deprecation warning. + Improve warning message when log4j is accessed after unload by Tomcat. + NullPointerException in NDC.remove after unload by Tomcat. + Configuring triggering/rolling policies should be supported through properties. + More explanations when hitting WARN No appenders could be found for logger. + Use Throwable.getStackTrace to obtain location when running on JDK 1.4 or later. + AsyncAppender fails on changing Throwable. + Extra NPE error message when using missing appender class with DOMConfigurator. + org.apache.log4j.varia.NullAppender lacks static accessor to static instance. + Javadoc for Appender.getName implies that the return value will be unique and not null. + Weekly rotation problem in Europe. + Add OSGi packaging info. + InterruptedIOException ignored by log4j. + HierarchyDynamicMBean missing unregister MBean + Support -Dm2_repo option on Maven build for non-default Maven repository location. + 2 tests for DateLayout are failing because of ill initialized DateFormat. + Incorrect user mailing list URL. + NTEventLogAppender.dll for 64-bit editions for Microsoft Windows. + Add configuration of ThrowableRenderers and add org.apache.log4j.EnhancedThrowableRenderer. + SMTPAppender does not force evaluation of message at request time + Support SSL transport in SMTPAppender + SMTPAppender should have a sendOnClose option + Support %X layout specification to output all MDC key-value pairs + Add replyTo attribute to SMTPAppender + SMTPAppender does not properly encode subject or content containing non-ASCII characters. + Clarify javadoc of Layout.ignoresThrowable. + SyslogAppender.append throws exception if layout is not set. + QuietWriter.write should check for null argument. + LogFactor5 CategoryPath doesn't replace slashes with dots. + LoggerDynamicMBean needs to handle a null Appender name. + DOMConfigurator.configure(URL) fails on JRE 1.5.0_16. + Document system properties used by log4j. + log4j is susceptible to exceptions in Exception.printStackTrace. + Misuse of "it's" in Javadoc for PatternLayout. + Add SMTPAppender.formatBody to simplify extension. + Failure when toString() of throwable performs logging in SocketAppender, SocketHubAppender and JDBCAppender. + Reading configuration files from a JAR locks the JAR file + PropertyConfigurator does not support configuring ErrorHandler. + log4j.ignoreTCL should apply to the getResource method in addition to the loadClass method of org.apache.log4j.helpers.Loader. + The QuietWriter class does not live up to its published contract. + More Debug output for log4j auto-configure requested. + Add MDC.clear(). + NullPointerException when calling Category.removeAllAppenders(). + Allow overriding of flush strategy. + Add recommendation to use EnhancedPatternLayout to avoid synchronization issues in PatternLayout + Source contains unnecessary imports. + Add LoggingEvent.removeProperty + Typo ("two three goals") in log4j FAQ + Unit tests fail for system dates after 2009-12-31 + Download page does not have link to KEYS file + Make LogMF, LogSF available in core log4j. + Add EnhancedPatternLayout from extras companion. + Links to example code broken in the JavaDocs + Unused imports and variables in test code cause gcj compile warnings. + Unit tests fail on Apache Harmony and gcj due to stack trace expectations. + SocketServerTestCase.test8 fails on Apache Harmony. + TestLogMF.testDebugDate fails on gcj. + TelnetAppenderTest.testIt fails on gcj. + Eclipse Java Compiler and gcj do not support -source=1.2. + CachedDateFormatTest fails on Apache Harmony. + Add %p{-2} pattern to EnhancedPatternLayout to drop two leading elements from name. + Add %throwable{n} and {-n} pattern to EnhancedPatternLayout to print n or drop last n lines. + + + + + log4j 1.2.15 release preparation. + Switch to NOPLoggerRepository if application reloading nulls repositorySelector. + Add 'application' property support to SocketAppender (from 1.3) + Log4JEntityResolver will return null if log4j.dtd can not be found on classpath. + HierarchyEventListener.removeAppenderEvent never called. + XMLLayout does not escape CDATA sections within NDC or throwables. + Added test to confirm that DOMConfigurator.configureAndWatch does configure. + Default initialization with XML file halts program if JAXP not available. + Add reset option to PropertyConfigurator and DOMConfigurator. + Error message always logged to LogLog when calling close on TelnetAppender. + Add configurable triggeringPolicy for SMTPAppender. + NullPointerException in MDC on Tomcat reload. + Notice to use UTF-8 or UTF-16 encoding added to XML and HTMLLayout javadoc. + XML and HTMLLayout do not always escape special characters. + Optionally render MDC content in XMLLayout + Typo in log4j.dtd concerning threshold. + ERFATestCase fails on some JDK's. + SocketNode can leak Sockets. + Migrate to Maven based build and documentation. + Prepare Maven release bundles. + Eclipse compiler warning cleanup. + JRockit VM and java-gcj fail unit tests. + SocketAppender does not use FallbackErrorHandler + Enhance DOMConfigurator to delegate unrecognized elements to configured object. + Add LoggingEvent accessors. + InstanceAlreadyExistsException using MBean. + Reduce first connection failure severity in SocketAppender + SyslogAppender does not limit packets to 1024 bytes. + SyslogAppender: Added "header" property which if set to true will cause the appender + to produce the HEADER part (timestamp and hostname) of the syslog packet. + Default value is false for compatibility with previous behavior. + SyslogAppender also now sends any header from the associated + layout when activateOptions is called or first logging event is sent and + any footer when the appender is closed. + SyslogAppender leaks descriptors + SyslogAppender assumes all lines start with tab + SyslogAppender does not limit packet size to 1024 bytes + + NTEventLogAppender: Updated NTEventLogAppender.dll which corrects missing event messages + and which should work with earlier releases of log4j. + NTEventLogAppender.dll also now supports registration and unregistration + using regsvr32. If replacing an existing copy of NTEventLogAppender, + use "regsvr32 NTDllEventLogAppender.dll" or manually remove the + HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Eventlog/Application/Log4J + registry key. + NTEventLogAppender.dll performs unnecessary code page conversion using code copied from book. + PropertyConfigurator.configure(URL) does not close resource stream. + In Turkish locale level "info" is not equivalent to "INFO" + Javadoc of PatternLayout should use %n in TTCC layout examples + Stacktraces of exceptions disappear occassionally + Incorrect message when specified custom level class does not implement toLevel + Warning when configuring inner-class logger + AsyncAppender in 1.2.14 DiscardSummary events create NullPointerExceptions in layouts + Add target to generate binary and source compatibility report + PropertyPrinter.printOptions breaking signature change in log4j 1.2.9 + RollingFileAppender may delete files during rollover + XMLConfiguration of loggerFactory does not work + SyslogAppender does not limit packet size to 1024 bytes + Update source per new ASF Header Policy. + DateLayoutTest fails if default Locale is not en_US. + Stacktrace may choke on null fields. + Add projects.apache.org project descriptor. + + + + Monitor deadlock in AsyncAppender. + AsyncAppender: Dispatcher should run at normal prio. + AsyncAppender wait forever when buffer is full. + Add non-blocking option for AsyncAppender. + Add SyslogPort option to SyslogAppender. + Add cc and bcc addresses to SMTPAppender. + Add password authentication to SMTPAppender. + NullPointerException in org.apache.log4j.NDC.get. + org.apache.log4j.lf5.util.DateFormatManager.setTimeZone assignment error. + Monthly logs not generated at midnight with DailyRollingFileAppender. + PatternLayout specifier %r is not consistent with documentation. + Space after log level causes default level to be used. + Bad patterns in ISO8601DateFormat and DateTimeDateFormat. + SyslogAppender throws NullPointerException upon misconfiguration. + FallbackErrorHandler throws NullPointerException if no loggers are set. + Bad documentation for WriterAppender.encoding. + NTEventLogAppender not build, tested and placed in distribution. + SMTPAppender does not output newlines between stack trace lines. + SMTPAppender will not run within sandbox. + MDC with SMTPAppender doesn't work. + Misspelling in HierarchyDynamicMBean. + Additivity not exported by PropertyPrinter. + RollingFileAppender, if removed, can cause NullPointerExceptions. + AsyncAppender blocks on thread death. + NOTICE file added to distribution and jars. + Chainsaw of log4j 1.2 does not show TRACE level. + TRACE level missing in short introduction to log4j. + Update site generation to velocity 1.4 and remove dependency on logging/site project. + + + + Location info missing for TRACE level messages. + Console appender now behaves as before to fix + compatibility problem with JBoss introduced in 1.2.12 release due to fix + for bug 31056. Can still be configured to detect changes in the System.out + and System.err streams as needed by setting the follow property. + + + + Removed final qualifiers on member variables + in org.apache.log4j.chainsaw.LoggingReceiver which would cause + spurious compiler errors with JDK 1.1 and 1.2 javac compilers. + + Added a jndi.jar property to the build.xml. + + Added "release" target to build.xml. + + Removed references to obsolete documentation. + + Added protected accessors for member variables + topicConnection, topicSession, and topicPublisher. + + SyslogAppender now checks Layout.ignoresThrowable() just + like every other appender. + + DOMConfigurator would call LogLog.error to report + XML validation errors that caused no problems in the interpretation of the + configuration file. + + Fixed the JavaDoc links + for the XML sample files. + + Added getNext/setNext methods to org.apache.log4j.spi.Filter and deprecated + public "next" field. This mirrors the same change in the upcoming 1.3 + version and, hence, provides a migration path. + + Added o.a.log4j.Logger.trace(), o.a.log4j.Logger.isTraceEnabled() and + o.a.log4j.Level.TRACE + + Implemented serialization for Level. + + o.a.log4j.ConsoleAppender would ignore redirections + of System.out and System.err that occurred after configuration. + + o.a.log4j.xml.DOMConfigurator would not properly + interpret relative path names in external entity declarations. + + o.a.log4j.xml.XmlLayout would not properly escape + class names that contained '<' or '>'. + + Use of String.intern() in o.a.log4j.CategoryKey + would cause application to slow down. + + o.a.log4j.FileAppender would not create log file + if parent directory did not exist. + + o.a.log4j.AsyncAppender would deadlock if a + unchecked exception occurred in the attached appender causing the + dispatch thread to die. + + Added jdiff target to build.xml. + + log4j would not build with a JDK 1.5 javac. + + Added log4j 1.1 compatibility method + to o.a.l.helpers.Loader. + + Additional null terminating character in Windows + nteventlog.cpp code. + + Broken links to J2SE classes in javadocs. + + + + + o.a.log4j.or.jms.MessageRenderer + would not be compiled in the build.jms target. + + + + Version 1.2.10 was not released following the accepted rules and process of + the log4j project and Logging Services Project and was recalled and removed. + Please do not use version 1.2.10, it is not an official log4j release. + + + + 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 + + + + + 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. + + Various versions of Xerces would not parse + log4j configuration scripts expressed in XML format. + + 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. + + SocketAppender now honors ReconnectionDelay of 0. + Many thanks to Scott Schram for reporting the bug and providing the fix. + + + + Log4j now searches for the file log4j.xml as well as the file + log4j.properties during log4j initialization. + + + + + Add of new options in JMSAppender and new command line arguments in + JMSSink. + + Add 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. + + Calling the MDC.get method with a null + argument would throw a NullPointerException. + + + + Calling an AsyncAppender close method also closes the embedded + appender instances. + + + + The JDBCAppender is marked as slated for replacement. Do not build + critical software using it. + + Add LF5 documentation and examples. Further tests are required + for full integration. + + XMLLayout can now output messages which contain embedded CDATA + sections.Many thanks to Michael + A. McAngus for supplying the relevant patch. + + The dispatcher thread associated with AsyncAppender is now marked + as a deamon thread. + + Add missing NTEventLogAppender.dll + + 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. + + Add missing LevelRangeFilter file. + + + + SyslogAppender would incorrectly compute + the length of the datagram to send to the remote syslogd host. + Reported by Mamoru Kadota. + + 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. + + + +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. + + + + + 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. + + + + + A closed TelnetAppender would continue waiting + for connections even if its ServerSocket was closed. This caused + the TelnetSocket to sit in a loop and complain about the closed + socket. + + AsyncAppender throws NullPointerException problem. The bug was actually in + AppenderSkeleton. + + Add support for recursive variable substiuton as requested by + Eric Chastan. + + SocketNode now used a BufferedInputStream as suggested by Kok Chong + + Fixed a problem with DailiyRollingAppender which would not + correctly compute the rollover period in certain timezones. + + Fixed documentation bug #2726 in FAQ.html. + + Added a flush statement in the + WriterAppender.writeFooter method. + + In XMLLayout, escaped the method attribute. The + XMLLayout also outputs each item of a stack trace in a separate + line. + + The + LoggingEvent.getMDCCopy method now clones the MDC instead of just + referencing it. + + The ANT build script was modified to use jar files specified in + the build.properties file instead of the CLASSPATH environment + variable. The build.properties file depends on local paths and is + supplied by the user. The build.properties.sample file is included + in the distribution. The build.sh and build.bat scripts have + been removed. This is the way many other jakarta projects build their + projects. The jar files in the dist/lib directory were also removed + since they are no longer used. + + The DOMConfigurator now interprets the string after the '#' + character in the value attribute within the <level> element as + the fully qualified class name of a custom Level. This is consistent + with the way log4j handles "level" values in other places. The + class attribute is still honored. + + Add Oliver Burn's chainsaw tool to the core log4j + distribution. Visualisation and dynamic filtering of log events is + bound to be a very important area of activity in the future. + + Add the org.apache.log4j.jdbc.JDBCAppender which as the name + indicates sends events to a database using the JDBC API. Thanks to + Kevin Steppe for supplying the code. + + Add SocketHubAppender class as contributed by Mark Womack. This + appender sends LoggingEvent objects to a set of remote a log + servers. + + In the Category class, the getChainedPriority method has been + replaced with getEffectiveLevel method. + + Replaced the custom class loading based on the thread context class + loader with a simple Class.forName() call. This solves two allied + but distinct problems encountered when using Ant with JUnit + although the bug is more general. In one instance of the + problem, log4j would throw java.lang.NoClassDefFoundError for + org/apache/log4j/AppenderSkeleton where log4j.jar and related + classes were clearly available to the Ant classloader. In another + incarnation, log4j would reject a custom appender claiming that it is + not assignable to a org.apache.log4j.Appender variable. This would + occur when log4j.jar was available to both the Ant classloader and the + system classloader. + + Thanks to Dave Herman for providing detailed scenarios exposing + the issues involved. See + http://forum.java.sun.com/thread.jsp?forum=38&thread=70946 + http://forum.java.sun.com/thread.jsp?forum=38&thread=70946#479697 + http://marc.theaimsgroup.com/?l=ant-user&m=101139178705895&w=2 + for more details. + + Fixed the complaints the compiler issued when using the + Logger.setLevel() method. + + Incorporated the performance enhancements to ISO8601DateFormat and + AbsoluteTimeDateFormat classes submitted by Andrew Vajoczki. + + Source code written for log4j 1.1.3.jar will compile fine with + log4j 1.2X. However, code compiled for log4j 1.1.3 would previously + systematically throw "java.lang.NoSuchMethodError" runtime exceptions + when run with log4j 1.2 - prior to beta2. This problem has been + corrected in beta2. Pheew, that was a close one. + + Log4j 1.2 is now backward compatible in serialization of + LoggingEvents. For example, a 1.1.3 SocketAppedner can write to 1.2 + SocketServer. Similarly a 1.2 JMSAppender will work with 1.1.3 + JMSSink. This should ease the move to log4j 1.2, especially in + large deployments. + + The src/java/org/apache/log4j/examples/ directory moved under the + top-level directory as examples/. + + Fixed the ArrayIndexOutOfBoundsException that was thrown by + AsyncAppender if multiple threads were trying to log an event + containing an exception near simultaneously. Thanks to Thomas Tuft Muller + for reporting this bug. + + Improved error reporting in DOMConfigurator. Thanks to Thomas Tuft + Muller for contributing the enhancement. + + Log4j is now configurable using JMX. JMX support is not of + production quality. + + Add support for different encodings in WriterAppender. Thanks to + Ben Sandee for submitting the relevant patch. + + Modified SMTPAppender to allow multiple email sessions. Thanks to + Jon Skeet for supplying the relevant patch. + + The CategoryFactory class has been replaced by the LoggerFactory + class. The makeNewCategoryInstance method has been renamed as + makeNewLoggerInstance. This change requires subclasses of Category + classes to be modified and recompiled. + + The Level class replaced the Priority class. Priority class now + extends Level to preserve backward compatibility. + + The Logger class replaced the Category class. Logger class + extends Category to preserve backward compatibility. We proudly + mark this change with a single star for 100% compatibility. + + The Category.assert method has been replaced by + Category.assertLog. This change was necessary because assert is a + language reserved word in JDK 1.4. + + Removed deprecated methods setOptions and getOptionStrings defined + in the org.apache.log4j.spi.OptionHandler interface. This interface + is implemented by most log4j appenders and layouts. In particular, + all appenders and layouts shipped with log4j contain these + deprecated methods. They have become totally redundant after we + moved to JavaBeans style configuration in log4j 1.1. + + The disable(Level) methods in Hierarchy have been removed and been + replaced by threshold methods. + + Add buffered IO capability to FileAppender and subclasses. + + The location information (or stack information) was not correctly + transmitted by JMSAppender. + + Add event reporting capability to the Hierarchy class. + + Add new system property "log4j.configuratorClass". This property + allows the user to specify the custom configurator at the default + initialization phase. This property replaces the previous + interpretation of the reference part of "log4j.configuration" + as the custom configurator class. This interpretation was sometimes + erroneous and caused headaches. + + Introduced the Mapped Diagnostic Context or MDC class. This class + is similar to the NDC except that the diagnostic context is based + on a map instead of a stack. Moreover the MDC is automatically + inherited by child threads under JDK 1.2 and above. + + Corrected a performance bug in the NDC class as observed by Dan + Milstein and independently by Ray Millard. + + Removed deprecated methods disable(Priority), disableAll, + disableDebug, disableInfo and enableAll in BasicConfigurator. + + Add supports java.io.Reader objects in the method doConfigure(), + instead of only InputStream. Thanks to Mark Womack for submitting + the relevant patch. + + Corrected the restart bug in DailyRollingFileAppender. Thanks to + Jim Moore for supplying the relevant patch. + + + + + Add a missing namespace declaration in the log4j:configuration + element in log4j.dtd. The missing declaration caused the new + generation of namespace aware parsers to barf when parsing log4j + configuration files. + + Reduced the size of log4j-core.jar to 78KB. + + Minor documentation changes. + + + + + Corrected a problem with the static initializer of the Category + class which would use the wrong class loader to search for the + default configuration file. The associated search algorithm has + been also simplified. Nevertheless, the preferred method to specify + the automatic configuration file is by setting the + log4j.configuration system property. + + Documentation improvements. Added a new section to the manual + explaining the default initialization procedure + + Enhancements to the org.apache.log4j.examples.appserver package. + + Corrected a bug in the way the NTEventLogAppender printed + exceptions. + + + + Add missing custom priority support in PropertyConfigurator. + +Made a number of fields protected instead of default access in + SMTPAppender. + + + + + This release has the same code as 1.1b7. It differs only in a few minor + documentation changes. + + + +Made BasicConfigurator disable methods static as they were in log4j + 1.0.4. Thanks to Francisco Marin for reporting the bug. + + Corrected a two related deadlock problems introduced while fixing + bug 1505. Thanks to joelr@viair.com for reporting the problem. + + The configureAndWatch methods in Configurators did not close the + configuration file, preventing its editing. + +In DOMConfigurator.setParameter special character conversion now + precedes variable substitution. This change was suggested by Steven + Velez. The vast majority of users should be oblivious to it. + +The TextPaneAppender is no longer maintained and has been + removed. It is still available under the contribs/ + directory. This change has been discussed in the log4j mailing + lists and no one objected to the removal of the TextPaneAppender + class. + + + +Aaron Greenhouse from Carnegie Mellon SCS found a series of + multi-threading related bugs in Category and AsyncAppender. See bug + ids 1505 and 1507 in our bug database for exemplary bug + reports. They are worth the detour. + + InvalidJarIndexException is only available in JDK 1.3. Referring + to this exception type caused log4j 1.1b5 to break on earlier JDKs. + We now avoid referring to it. + + Add PriorityRangeFilter by Simon Kitching. See the Threshold + option in AppenderSkeleton for a more convenient alternative. + + + +In HTMLLayout, the Title option sets the HTML document + title (<title>...<title>). + +Corrected an important performance bug in LocationInfo. Hein Couwet + and kr@it-practice.dk have independently identified the bug. This is + yet another example of the difference made by the number of eyeballs + studying source code. + + Corrected the incorrect value returned by LocationInfo.getClassName + method when running under IBM Visual Age. Thanks to Mathias + Rupprecht for supplying the relevant patch. + + Corrected a bug where the build.sh file in the distribution would be in + DOS CRLF format. Thanks to ma.darche@free.fr for reporting the + problem. + + Corrected InvalidJarIndexException thrown in applets while + searching for the default log4j configuration file. Thanks to + Michael Lundahl for reporting this bug. + + Add missing PropertySetterException class to log4j-core.jar. + Thanks to ma.darche@free.fr for reporting this bug. + + + +Mathias Bogaert observed that in version 1.1b3 the search algorithm + for the resource used in automatic log4j configuration was + different than in 1.0.x. Beta4 uses a more powerful mechanism which + is also compatible with 1.0.x. + + Paul Glezen correctly observed that if log4j is deployed in a + client/server mode where multiple log4j clients log to a log4j + server, all hosts must be upgraded to version 1.1 in one go because + the internal LoggingEvent class used in client/server communication + changed in log4j 1.1. + + + + Add a RollingFileAppenderBeanInfo class that fakes the + maxFileSize JavaBeans property as a String type instead of a long. + This allows us to resuscitate setMaxFileSize(long) method that was + removed in 1.1b2 breaking 100% backward compatibility. This addition + restores 100% backward compatibility. + + + + + The directory structure has changed to better suit Jakarta + conventions + + Add a few jar files required at build time to build/lib so that + it is now possible to compile log4j out of the box. + + Whenever a priority parameter is expected in a configuration file, + one can now use a custom priority class. See OptionConverter.toPriority + method for more information. Note that the <priority> element in + log4j.dtd remains unaffected by this change. + + Add the setQuietMode(boolean) method to LogLog. In quiet mode + LogLog will not output anything even in case of errors. + + Log4j components are now configured as JavaBeans. The setOption and + getOptionString methods have been deprecated in OptionHandler + interface which is implemented by most log4j components. + + The stack trace of a throwable passed in a logging statement is not + parsed into a stack array which is serializable. This allows cascading of + log4j servers to properly propagate throwable information. + + In XML configuration files, the <configuration> element has been + deprecated and was replaced by the <log4j:configuration> element. + + The "log4j.configDebug" system property has been replaced with the + "log4j.debug" system property although it is still available. + Similarly, the "configDebug" attribute has been deprecated and + replaced with the "debug" attribute in log4j.dtd. + + + + + Logging can now be disabled per Hierarchy. It can also be disabled + using configuration files using the "disable" directive. The + "disableOverride" directive takes precedence over the "disable" + directive. As a result of this change the disable family of + methods in BasicConfigurator has been deprecated and replaced by the same + family of methods in the Hierarchy class. + + The FileAppender has been split into three parts: WriterAppender, + ConsoleAppender and FileAppender. ConsoleAppender takes over the + console logging functionality of FileAppender. As a result support + for stream and console printing has been deprecated in FileAppender. + + The FileAppender now correctly outputs the header and footer of its + layout. This problem was reported by too many users to list here. + + Appenders and Layouts now get to see the raw message object in + LoggingEvent not just its rendered form. The access modifiers of + some LoggingEvent fields were changed so that they can be accessed + in less error-prone ways. Thanks to Jim Cakalic and Anders Kristens + for their valuable advice. + + Add getLayout(), getErrorHandler(), and getFilter() to the + Appender interface. + + Add getOption(key) method to the OptionHandler interface and modified + implementations of it as appropriate. + + Add the much awaited DailyRollingFileAppender. + + The structure of the distribution changed somewhat. The log4j.jar + files can be found under dist/. The javadoc directory has been + moved to docs/api/. We are now totally dependent on ANT to perform + all the steps involved in creating a release, including + compilation, jar file creation, generation of the javadocs, and for + the creation of the distribution tar and zip files. + + Removed org/apache/log4j/varia/ResilientFileAppender.java which was + bogus to begin with. + + XMLLayout will now mark some output as <![CDATA[ .. ]]> so that it + does not get interpreted by the XML parser. This was suggested by + Mathias Bogaert like a long list of other fixes. + +Corrected a bug in CyclicBuffer.resize method that would not update the + next insertion point. Thanks to Ole Bulbuk for accurately reporting + the bug. + +The LoggingEvent class now supports serialization of priorities + derived from the org.apache.log4j.Priority class. + +Improved the search method for finding the "log4j.properties" file in + the static initializer of Category class. Thanks to Calvin Chan for + supplying a better method. + +The code handling the FCQN (formerly instanceFQN) parameter was + cleaned up. There is now a well-established and simple manner for + sub-classes of Category (or wrapper classes) to define the FCQN + variable: just define a static variable, say FCQN, consisting of + the fully qualified class name of the subclass or wrapper, supply + this variable as an argument to forcedLog method if and when + the sub-class or wrapper invokes that method. + +Made the instanceFCQN an instance variable instead of a class + static in Category.java. In related move, the Category constructor + now takes an additional argument setting the instanceFCQN. This + makes life less miserable for Category subclasses. + +Corrected a bug in the OptionConverter.instantiateByClassName + method that would not return the defaultValue in case of error. Thanks + to Matthieu Verbert for identifying this bug. + +Corrected the missing stack trace in e-mails generated by the + SMTPAppender when using certain Layouts. + +Updated the "Adding Conversion Characters to PatternLayout" + document to reflect the latest changes to the code. Also added the + org/apache/log4j/examples/appserver directory containing the + associated example code. + + Add the BufferSize option to the AsyncAppender. + +Eliminated the SecurityExceptions thrown in Applets. Thanks Timur + Zambalayev for reporting this bug. + +Fixed the erroneously thrown IOInterruptedException when the AsyncAppender + was closed. Thanks to Tom Palmer for accurately reporting this bug. + + + + + +Corrected a serious bug in Hierarchy.java that would cause a + NullPointerException depending on the order of instantiation of + categories. Thanks to Wolfram Gewohn for reporting this bug. + +Corrected a bug in the getOptionsStrings method of SMTPAppender + that omitted to mention the EvaluatorClass option. Thanks to Mark + Balster for reporting this bug. + + + + +Fixed a NullPointerException occurring in AsyncAppender after + invoking Category.shutdown. Thanks to Frank-Olaf Lohmann for + reporting this bug. + +Modified the OptionConverter.selectAndConfigure method to take an + extra argument of type Hierarchy. This method is used internally + and should not affect most users. + + Add the warn method to LogLog which is used internally by log4j + to report on itself. + +Displaced a number of HTML files under the docs directory. The new + structure is compatible with the jakarta site and results in a + more consistent navigation experience. + +Made a few improvements in the javadocs. + + + + + Add the missing build.inc file to the distribution. No code + changed. + + + + + +This version corrects some documentation and build script bugs; + code has not changed. + + + + +Package hierarchy now starts at org.apache.log4j. + + Add the fatal() family of methods to the Category + class. Moreover, the EMERG priority has been removed from the + Priority class. This priority has been replaced by the FATAL + priority that is more widely accepted. This change will + require EMERG log statements to be replaced by FATAL log + statements. Assuming EMERG log statements are rare, this should + have a small but bearable impact on existing client code. + + Moreover, the Unix Syslog priorities ALERT, CRIT and NOTICE are no + longer recognized. Support for these priorities was minimal and + few users should suffer from these changes. + +Removed the methods setRootPriority, getRootPriority as these + methods were redundant and had been previously deprecated. + +Removed the DOM Level 2 dependency in DOMConfigurator. This makes + log4j XML configurable using Sun's parser or Apache's Xerces. + +The static initializer of the Category class now takes the + log4j.configuration system property to search for its configuration + file. The type of the configurator used to parse the configuration + file depends on the value of the log4j.configuration system + property. + +Enhanced the PropertyConfigurator and DOMConfigurator to support + customisation of independent Hierarchy instances. The + org.apache.log4j.net.SocketServer has been enhanced to take + advantage of this functionality. The old code of SocketServer has + been moved to SimpleSocketServer. + +Enhanced the PropertyConfigurator to support variable substitution + for all options *values* (but not keys!). + +Categories are now aware of the Hierarchy they are linked to. This + will provide a basis for several performance enhancements planned + for the future. + + Add support for object rendering. It is now possible to register + an object renderer for a given object type. When the given object + needs to be logged log4j will invoke the corresponding renderer to + transform the object into a String. + + As a result of this enhancement, all the String forms of all the + printing methods such as debug(String), info(String) have been + removed as they are no longer necessary. This change should be + backward compatible but requires recompilation of old client + code. Thanks to Michael Smith for noting the recompilation + requirement. + + Add support for user defined category factories in the + PropertyConfigurator. Thus, it is now possible to configure log4j + with a properties file and still use custom Category + sub-classes. The DOMConfigurator had already a finer grain + support. + + Add the SMTPAppender that in case of an error or fatal event + sends an e-mail containing latest N logging events in its buffer, + where N is chosen by the user. + + Add the method getInstance(Class) to the Category class. + +Corrected a bug in configureAndWatch method of configurators that + would configure log4j only after an unnecessary delay. + + + + +Corrected a typo making NTEventLogAppender.dll register the wrong + category message file. Thanks to Peter Hayes for accurately + reporting this bug. + +The DOMConfigurator and PropertyConfigurator can now automatically + detect modified configuration files and re-read them. + + Add AsyncAppender which buffers log requests and serves them + at a later time. AsyncAppender can increase logging performance + tremendously if logging operations are interspersed with long + and blocking non CPU-intensive operations, typically I/O or network + access. For CPU intensive applications, using the AsyncAppender + will actualy degrade logging performance by 10 to 25 percent. + +The log4j.dtd has been modified to allow appenders to refer to + other appenders by IDREF. + +The DOMConfigurator has been modified to take advantage of ID/IDREF + attributes when referring to appenders. This change requires a + DOM Level-2 API compliant parser. DOM Level-2 java bindings are + available at + http://www.w3.org/TR/1999/WD-DOM-Level-2-19990923/java-binding.html. + + Add the configure(String filename) method to DOMConfigurator. + This method requires the presence of a JAXP compatible parser. + At this time, the only DOM2 and JAXP compatible parser seems to be + the Apache xerces parser. + + Add the PriorityMatchFilter allowing filtering by exact priority + match. This was a common request by users. + +The configuration of a category is now an atomic operation. This + ensures that log requests are not lost while configuration is in + progress. Anders Kristensen was to first to observe the potential + problems in non-atomic configurations. + + + + +The "log4j" element has been renamed to "configuration" in the + log4j DTD. This change requires that log4j configuration files + written in XML be modified. Since the log4j element figures only + once in the XML file, this change should take little time. + +ResourceBundles are now category instance specific and no longer + class static. Moreover, like other properties resource bundles + are inherited from the category hierarchy. + +The jar files log4j.jar and log4j-full.jar now contain versioning + information in their respective manifest files. + +Corrected an inconsistency in the NTEventLogAppender which broke it. + +Fixed a bug where configuration files were not parsed correctely + due to trailing spaces in option values as returned by + java.util.Properties. Trailing spaces are now removed from option + values. This bug was quite disconcerting because the + trailing spaces cannot be seen without careful examination of the + configuration file. + + Add the XMLLayout. + + The output of the XMLLayout consists of a series of log4j:event + elements. It does not output a complete XML file. The output is designed to + be included as an external entity to form a well-formed XML file. + + Add a new abstract class org.log4j.helpers.DateLayout. The TTCCLayout + now extends DateLayout. + +Corrected a rather subtle performance bug in the buffer management code + in PatternLayout. Thanks to Vladislav Dutov and Constantine + A. Plotnikov for for insisting on the correction of this bug. + +Created a new package called org.log4j.spi. This new package + holds classes that are hidden from the casual user but are needed + to extend log4j. + + Add org.log4j.varia.ExternallyRolledFileAppender to handle + externally triggered file rollovers. + + Add support for multiple hierarchy trees. + +PatternLayout can now be subclassed to support new conversion + patterns. + +Extended the DOMConfigurator and the log4j DTD to properly handle + sub-classing of Category and Priority classes. + There have been also minor adjustments to other classes to handle + sub-classing. These changes should be invisible to users. + + All categories except the root category can be sub-classed and also + assigned priorities sub-classing org.log4j.Priority. + + The root category always exists and CANNOT be subclassed. + + The ProppertyConfigurator remains unchanged. Thus, it does not + handle extensions of the Category class. + + Add filter support in appenders. The DOMConfigurator and the + log4j.dtd have been enhanced to support filters. + + Add error handling support to appenders. The DOMConfigurator and the + log4j.dtd have been enhanced to support filters. + + Add support for correct interpretation of location information in + IBM's Visual Age environment. Thanks to Wolf Siberski for supplying + the relevant patch. + + Add getAdditivity method to Category. This feature was requested + by Constantin Mitran. (mitran at ecircle.de) + + + + +Corrected multiple bugs in default initialization code of + Category class. Thanks to Jeff Turner for identifying and supplying + corrective patches. + + + + + Add the %n conversion character to PatternLayout so that a line + separator can be specified in a platform independent way. + +In 0.8.5 internal Priority integer values were decoupled from the + Unix Syslog values. This broke SyslogAppedder. A new function + Priority.toSyslogInt is introduced to solve this bug. + +Corrected a bug where the internal priority integer + + + + +All log4j internal output is now prepended with the string + "log4j: ". This makes is easier to differentiate log4j internal + logs from messages output by other sources. + +Sub-classes of Category class must now specify their fully + qualified name when constructing logging events. This allows the %C + conversion specifier in PatternLayout to work properly even with + sub-classes or wrappers of Category. + + Add the method disableDebug to BasicConfigurator. This method + disables all print requests of debug priority regardless its + category. Similar methods disableInfo, disable, disableAll and + enableAll have also been added. Disable type methods can be + overriden by setting the log4j.disableOverride system property. + + Calling BasicConfigurator.disableInfo is equivalent to the now + deprecated flagAsShippedCode method. + +Given the above changes, the system property + log4j.shippedCodeFlagOverride is no longer honored. + +It is now possible to sub-class Category. The sub-classes may + continue to adhere to the category hierarchy. This was a frequently + requested feature. + +Corrected a problem with the additivity flag being ignored in + categories without appenders. This bug was discovered by Anders + Kristensen. + + Add a method BasicConfigurator.resetConfiguration to reset the + log4j environment. This method should be used sparingly. + +At the initialization of the Category class, the file + log4j.properties will now be searched from the search path used to + load classes. If the file can be found, then it is fed to the + PropertyConfigurator.configure(java.net.URL) method. + +Failing to access system properties within the static initializer + of BasicConfigurator class is no longer reported as an error but as + a debug message. Thanks to Gilles Schlienger for reporting this + problem with applets. + +Corrected a bug which caused infinite loops when using conversion + patterns with a single element, fortunately under very rare + circumstances. This bug was first reported by Igor Potraev, the + author of log4p. It was independently reported by Joe Haberl from + IBM Global Services. + + Add a mechanism to lazily remove references to dead threads in + the NDC class. Indeed, in previous versions calling NDC.pop within + a thread but forgetting to call to NDC.remove before exiting (that + thread) resulted in a memory leak. + +Corrected a huge memory leak in SocketAppender. This leak was due + to the ObjectOutputStream indefinitely holding a reference for each + written to the stream. Thanks to Dan MacDonald for very accurately + describing this bug. + +The log and l7dlog methods in Category no longer ignore the shipped + code flag. This bug was reported by Mario Schomburg. + + Add missing NDC information to LoggingEvent.writeObject + method. + +Corrected handling of SocketException in SocketNode. Thanks to + Gerald Gutierez (ggutierez@emobiledata.com) for reporting this and + the previous problem. + +Phased out custom shell scripts to build java documentation and jar + files in favor of Jakarta's ANT. It was becoming a nuisance to keep + the ANT build file in sync with the custom shell scripts. + + + + + + +The NT EventViewer no longer complains about missing message 4096. + +Minor corrections in documentation. + + Add missing icons GIFs into the distribution. + +SocketNode now attempts to close the socket when exiting. Thanks to + Moses Hohman (mmhohman@rainbow.uchicago.edu) for noting this. + +Removed the com.ibm.log4j from the javadoc directory. This seems to + confuse VAJ. Thanks to Steve Ashcroft for reporting this problem. + + + + +As a result of the infinite loop problem (see next item), added + over 800 new test cases to stress-test the code in CategoryFactory + class where category creation occurs. + +Under certain rare circumstances the Category.getInstance method + entered an infinite loop. Thanks to Mario Schomburg from IBM Global + Services / Hannover for identifying this problem and proposing a + patch. + +DOMConfigurator and the log4j.dtd were out of sync on the type of + the priority directive. As a result, priority directives all + defaulted to DEBUG. Thanks to Peter (petervt@users.sourceforge.net) + for accurately reporting this bug. + +Minor additions to the FAQ. + + Add the NumberCruncher example showing how the NDC class can be + used to distinguish output from different clients. + + Add the %x conversion specifier to the TTCC_CONVERSION_PATTERN in + the PatternLayout class. This is consistent expected output of + Trivial.java example. Thanks to Jerome (schrom@users.sourceforge.net) + for reporting this bug. + + + + + +The value of the additivity option would not be parsed properly by + the ProperytConfigurator if the line containing the option + contained trailing spaces. + + + + +The localized logging methods (l7dlog) omitted priority based + evaluation and erroneously logged all requests. + + + + + +The close method was added to the Appender interface allowing + appender implementations to release any resources they may have + allocated. + +The package naming scheme of changed from "com.ibm.log4j.*" to + "org.log4j.*". The new naming reflects the open source nature of + the project and is consistent with the URL http://www.log4j.org. + + Add internationalization support. See the newly introduced l7dlog + methods in Category class. + +In the FileAppender, the File option now admits variable + substitution. For example, if "java.home" system property is set + to /home/xyz and the File option is given the value + "%{java.home}/test.log", then File option will be interpreted as + "/home/xyz/test.log". + + Thanks to Avy Sharell (sharell@online.fr) for contributing this + feature. + +SocketAppender is now officially part of the package. It is capable + of sending logging events to a remote SocketNode. The SocketNode + logs events according to server (local) policy. For example, a + client can log events to a local file and also send them to a + remote server (a SocketNode). This server can log the event to any + number of files, to the console, to any number of TextPaneAppenders + and even re-transmit the event to another server, and so forth. + + This paradigm is common in most logging systems, e.g. Syslog and NT + Event Log. Many thanks to Andrew Harrison for showing a way to + actually implement the paradigm. + +The Category.callAppenders method now accepts a LoggingEvent + instead of creating one itself. This was necessary to accommodate + events generated at a remote client. + +LoggingEvent class changed slightly to support remote logging. The + category field (a Category) has been replaced by the categoryName + field (a String). + + + + +Corrected a bug in Category.removeAppender(String) which would + never remove the desired appender. Thanks to Moses Hohman for + reporting this bug. + + + + +Corrected a bug RollingFileAppender which would throw an uncaught + exception in case output file could not be opened for + writing. Thanks to Vinay Aggarwal for signaling this problem. + + + + +The log4j.override key defined in BasicConfigurator has been + renamed to log4j.shippedCodeFlagOverride. + +The getCurrentCategories method in the Category class would not + return the correct value. Thanks to Timothy Potter + (tpotter@agency.com) for reporting this problem. + +Appenders now admit a priority threshold as an option. All requests + with a priority lower than the appender's threshold priority are + ignored by the appender. + +Integrated Christopher Taylor's DOMConfigurator parsing XML + configuration files. + +The jar file log4j-net.jar has been replaced by log4j-full.jar. It + contains DOMConfigurator.class in addition to the com.ibm.log4j.net + package. + + Add support for the ANT build tool. Thanks to Christopher Taylor + for supplying the build.xml file. ANT is available form + http://jakarta.apache.org. + +FileAppender's File option now accepts the values "System.out" or + "System.err". If one these values is suppiled in a configuration + file then the output is directed to the corresponding stream. + Moreover, the default constructor of FileAppender no longer sets + System.out as an output target nor does it define a default + layout. + + Add caller class (C), caller file name (F), caller line number + (L), caller method name (M) conversion specifiers to the + PatternLayout class. + + The category conversion specifier now takes an optional precision + modifier allowing the user to control the number of right most + components in the category name that will be printed. + + Corrected a bug occuring when the caller file name and line number + information were unavilable due to JIT compilation. In that case, + the PatternLayout would not properly use the rest of the available + location information. + + The above enhancements and bug-fixes originate from comments by + Nelson Minar (nelson@monkey.org). + + + + +The SimpleLayout and TTCCLayout are replaced by the PatternLayout + in the log4j.jar file to keep its size small. These two layouts are + still part of the package. + +The PatternLayout class is introduced. This new layout is + configurable using a conversion pattern which is parsed at + runtime. This allows the user to choose the output layout without + writing any code and only at a marginal performance cost compared + to the dedicated layouts such as SimpleLayout and TTCCLayout. The + PatternLayout also allows the user to determine minimum and maximum + field lengths. + + The PatternLayout was written by Jim Cakalic + (jim_cakalic@na.biomerieux.com). + +All internal components now use LoggingEvent instances to specifiy + logging information. + +Corrected a problem with a missing variable initialization in + SyslogAppender. This caused NullPinterException to be thrown when + logging exceptions. + + Added a default constructor to SyslogAppender. The lack of this + constructor caused PropertyConfigurator to throw a + java.lang.InstantiationException when the appender type was set to + be SyslogAppender. + + Thanks to Yves Bossel (ybossel@opengets.cl) for accurately + identifying these bugs. + + Modified some other related option handling code in + SyslogAppender. + +Made NDC.get public access instead of default access. Thanks to + Y. J. Chun (monac@softonnet.com) for reporting this problem. + +PropertyConfigurator now parses the additivity option for + categories. + +Corrected the value of the ADDITIVITY_PREFIX constant to match the + documented value, that is "log4j.additivity". + +Corrected a really bad bug where System.out would be closed when + PropertyConfigurator.configure was called. Thanks to Christopher + Taylor (cstaylor@pacbell.net) for tracking and reporting this bug. + +The PropertyConfiguator now prints debug messages if the flag + "log4j.configDebug" is defined in the configuration + file. Previously, only if the system property "log4j.configDebug" + was set would debug messages be printed. A question by Shawn + Kircher (skircher@vninet.com) induced this change. + +In AbsoluteTimeDateFormat, DateTimeDateFormat and ISO8601DateFormat + the separator between the seconds and milliseconds has been changed + to comma from full stop, in order to be compliant with ISO8601's + preferred sign. Thanks to Jim Cakalic + (jim_cakalic@na.biomerieux.com) for pointing out this discrepancy + with the standard. + +Corrected a bug where RollingFileAppender would not work + properly on Windows systems. Thanks to Heinz Richter + (heinz.richter@ecmwf.int) for noting this problem. + + + + +Core classes are now independent of the format of the options + file. Configurable core classes implement the OptionHandler + interface. OptionHandlers allows configurators to learn the + relevant option names. The configurator feeds option values to the + OptionHandler which configures itself. + + As a result of these changes, the Init class has been broken down + to two separate classes: the BasicConfigurator and the + PropertiesConfigurator. + + An XML configurator for 0.8.0 has been already written by + Christopher Taylor (cstaylor@pacbell.net). + + Add multiple appender support per category. The appenders follow + the category hierarchy, i.e. a child category inherits the + appenders of its parents. + + Add an assert() method to the Category class. Steven Marcus + (srnm@awaretechnologies.com) requested this addition. + +Automatic stack printing is no longer supported. This was an unused + and unreliable feature which unnecessarily complicated the + code. + +log4j now emits a single warning message when no appender to write to + could be found. This is typically the case when the user forgets + to configure the log4j environment. This change was suggested by + Jim Cakalic (jim_cakalic@na.biomerieux.com). + +RollingFileAppender adds file roll over capability-implemented by + Heinz Richter (heinz.richter@ecmwf.int). + +Corrected a bug where a java.lang.NoClassDefFoundError would be + thrown because com.ibm.log4j.helpers.SyslogTracerPrintWriter was + not included in log4j.jar. Thanks to Jim Cakalic (jim_cakalic@na.biomerieux.com) + for signaling this bug. + + + + + +There has been an important API changes. The Log, NOPLog and ILog + classes have been removed. Their functionality has been migrated to + the Category class. + + In this release, instead of writing + + ILog.debug(CAT, "Some message."); + + one will write + + CAT.debug("Some message."); + + Arndt Schoenewald <arndt@ibm23093i821.mc.schoenewald.de> observed that + one could use the Category objects directly for logging. + +It is no longer possible to instantiate Category objects directly. + Instead, one would use the factory method + Category.getInstance(String name). [***] + + There category instantiation code was moved to CateogryFactory + class. This class has package visibility and remains hidden from + the user. + + This stylistic improvement was suggested by Luke Blanshard + (luke@quiq.com). + +The Init class offers methods to initialize the log4j + environment. The Init.flagAsShippedCode method replaces the NOPLog + class. + +Changes in the documentation to reflect the API changes. + +The NDC.cloneStack and inherit methods now tolerate null-stacks. + + + + + +TTCCLayout now takes a java.text.DateFormat object as a + parameter. The task of formatting the date is delegated to this + object. + + Added four classes extending the java.text.DateFormat class. These + are RelativeTimeDateFormat, AbsoluteTimeDateFormat, + DateTimeDateFormat and ISO8601DateFormat classes. + + Thanks to Arndt Schoenewald <arndt@ibm23093i821.mc.schoenewald.de> + for suggesting the ISO8601 date format. + + These four classes can be parametrized with a particular + TimeZone. The TTCCLayout class now accepts a new configuration file + option called "TimeZone". + + These four DateFormats are less malleable than the + java.text.SimpleDateFormat but they are also much faster. + + As a consequence of these changes, the setRelativeTime, + setDatePrinting methods in TTCCLayout have been removed along with + the associated configuration file options RelativeTime, + DatePrinting and TimePrinting. + + The current code is inspired by code contributed by + Heinz Richter (heinz.richter@ecmwf.int). + +The Log.emerg method has been deprecated. If you use statements of + EMERG priority, please use the Log.log form instead. + + Add getDepth and setMaxdepth methods to the NDC class. This makes + it easier to manage the nested context depth especially when + callees push but forget to pop. + +Moved the documentation in com/ibm/log4j/package.html to + com/ibm/log4j/overview.html. Many users were failing to read the + com/ibm/log4j/package.html description due to the unfortunate + layout of the text. Hopefully more people will read the package + overview in its present location. + + Add the com.ibm.log4j.net package for doing remote logging using + TCP sockets. This is still experimental code. + + Add new debug, .., emerg methods that do not require a category + parameter. They assume the "root" category, that is the decision to + whether print or not is made by comparing the statement's priority + with the default priority. + + + + + Add a new ILog.init method accepting an Appender and a + configuration file as parameters. + +FileAppender's setWriter and setFile methods where not instantiating + a new tracer. This caused stack traces to be lost! SyslogAppender + had a similar problem. + +The FileAppender and SyslogAppender where not calling the layout's + readConfig method to set layout specific options. Thanks to Heinz + Richter (heinz.richter@ecmwf.int) for reporting this bug. + +Corrected a bug in Log.log() method where the appender was always + called with Priority.DEBUG. Thanks to Oliver Boehm + (Oliver.Boehm@abaxx.de) for reporting this bug. + + + + + Add Syslog compatibility. One can now choose (at runtime) between + remote syslog logging or file logging. + Syslog logging performance, although not appalling, is significantly + slower than file logging. + +Priority class was enriched with the previously missing priorities + NOTICE, ALERT and CRIT. The internal constants were also aligned with + the syslog counterparts. + + Add the Log.log method to support the new priorities. + +TracerPrintWriter is now an independent class instead of being a + nested top-level class in Tracer. + +A number of writers, namely the SyslogWriter, SyslogQuietWriter, + SyslogTracerPrintWriter, were added to the helper package. + +Log.force method was removed. The various Appender.doAppend + implementations take over its functionality. + +FileAppender and SyslogAppender now use QuietWriter. QuietWriter is + a FilterWriter which hides exceptions and instead emits a single + warning message to System.err. + +The layout is now an initialization parameter to the appender + type. Previously, the layout and the appender where independent + parameters to the Log constructor. + +Many small improvements and corrections in the documentation. + Syslog related documentation remains sparse. + +ILog.init() and ILog.init(String configFile) have been changed to + call ILog.init(,,,) with "com.ibm.log4j.Log.class" as the first + parameter. This makes it easier for people to get familiar with log4j. + + Add missing files to the make directory. These files are useful + for those wishing to use the log4j make environment. Thanks to "Lee + Hall" <LHall@JavaFoundry.com> for reporting this omission. + Until recently the make environment failed to compile RMI stubs in + a single run. This nagging problem has been corrected thanks to + help from Thomas Eirich (IBM Zurich Research Lab). + + + + +Some users have been rightly complaining about the verbosity + TTCCLayout's date output. The full date output is now shortened to + "dd MMM YYYY HH:mm:ss.SSS" for example, "06 Nov 1994 08:49:37.459" + In addition, users may now choose to print only time information, + as in "08:49:37.459". + +The package now uses Writer instead of OutputStream as its output + target. This makes the log4j code smaller and easier to + understand at the cost of a slight performance degradation. As a + result of this change a few method names in FileAppender class were + changed. + +Preliminary experiments with SyslogAppedner and SyslogLayout show + that syslog compatibility is not far away. The difficultly is + adding syslog compatibility without making radical changes to the + current log4j architecture. + +Corrected a bug in the NOPLog.createInstance method which always + created a Log singleton even if the system property "log4j.logType" + was set to NOPLog. Thanks to Robert Gottofrey + (Robert.Gottofrey@wdr.com) for reporting this bug and the + associated test case. + +Removed the inconsistent "Layout" configuration option in + Log.readConfig(). This change should be transparent to most + users. + + + + +The LogCreationManager class has been removed. Its functionality + has been transfered to the createInstance and getInstance methods + in the Log and NOPLog classes. The new way of creating instances is + both simpler and less error prone although just as flexible. + + As a result of these changes, the init family of methods in the + ILog class have been adjusted to the new way of creating the log + singleton. + +The Appender interface has been introduced. The method of writing a + log statement into an output stream can now be varied by using a + different Appender. The new FileAppender offers the same + functionality that was previously part of the Log class. + +Changed the time format used in TTCCLayout to be of the form "Day, + dd MMM YYYY HH:mm:ss.SSS GMT" for example, "Sun, 06 Nov 1994 + 22:49:37.459 GMT". This format is almost the same as the format + specified in RFC 1123 and also the format recommended in RFC + 2616. The only difference is the additional milliseconds + information. + +The layout specific options were not read from the configuration + file due to a missing instruction. Many thanks to Vikram Sridharan + (Vikram.Sridharan@alysis.com) to patiently pointing out this + omission to an unbelieving maintainer. + + + + +Version 0.7.0 and above will be distributed under the IBM Public + License (IPL). The IPL is an approved open source license (see + http://www.opensource.org/licenses/ for a list). It grants similar + rights to the previous ALPHAWORKS license agreement, in particular, + the right to redistribute and to modify the package. + +The Log class can now be parameterized with a Layout object. + Layouts determine the format of what is printed, where as the Log + class decides when to print and to where. + + As a result of this modularization, the CGULog and NOPCGULog + classes no longer exists. CGULog class has been replaced with the + TTCCLayout (Time Thread Context Category). This should make it + easier to create new log output formats. + + Some time in the near future, the Log class will be further broken + down to allow different strategies for writing to output streams. + +Renamed com.ibm.util.log hierarchy to to com.ibm.log4j. I wanted to + do this for some time. I feel release 0.7.0 was the last + opportunity to do so. I am sorry for the the trouble caused by this + change. + +New NDC class. This class implements nested diagnostic contexts as + suggested by Neil Harrison in the article "Patterns for Logging + Diagnostic Messages" part of the book "Pattern Languages of Program + Design 3" edited by Martin et al. Nested diagnostic contexts is a + nifty feature that was missing up to now. + + The StressNDC test class seems to break JDK 1.2.2 beta on AIX. On + Linux and NT using sun's JDK 1.2.2 it seem to work OK. In any case, + tests done with StressNDC and associated perl script seem to + indicate that the NDC class is bug-free. + +Corrected a date formatting bug in CGULog class where on some + environments the wrong month was printed. Thanks to Christopher + Williams (Christopher_Williams@mail.northgrum.com) for signaling + this bug. Also changed the month format from a number to a three + letter abbreviation such as "Jan", "Feb", ..., "Dec". The new + format is unambiguous regardless of local date format. + + + + +Clearer documentation with still much room for improvement. + +Corrected a bug in the Tracer class which always used the Unix line + separator instead of the system specific separator. Thanks to + Vikram Sridharan (Vikram.Sridharan@alysis.com) for singaling this + bug. + +Corrected a runaway comment which gulped the CGULog.readConfig + method. + + Add the init family of methods to the ILog class to ease the + setup of a basic logging environment. Thanks to Mark Donszelmann + (Mark.Donszelmann@cern.ch) for this enhancement. + +Just an hour after releasing version 0.6.1 detected and corrected a + bug where the Tracer class would correctly print Exception stack + trace but not the type of the Exception. Replaced the + distribution on www.zurich.ibm.com without changing the version + number. I hope nobody is using the intermediary (and buggy) release + of 0.6.1. + + + + +Better documentation with still much room for improvement. + +For consistence sake, added setDefaultPriority and + getDefaultPriority methods to the Category class and deprecated + setDefaultPriority in the Log.class. + +Corrected a major bug where if two categories were homonyms the + second instance would not be properly initialized. + +Increased the speed of Exception logging from about 4000 + microseconds to about 1000. It seems that for some people Exception + logging is performance critical. Improved implementation is a + variant of Nocolai's (XNH@crisplant.com) implementation. + + + + +Release of log4j 0.6.0 with incomplete documentation. + + Add a stress test program to debug the new Category class. It + turns out that the test program was as hard to get right as the + Category class. Given the favorable results of the stress test I am + quite confident that the new class is now bug free. This assumption + has been proven to be wrong. See above. + +Created a new class called Category to manipulate categories + instead of plain Strings. The new class is just as easy to use. + However, the evaluation of whether to log or not to log is at least + 10 times faster. The NOP class performance remain unaffected by the + change. (You can't improve on the performance of an empty function + call.) + + Many thanks to Alex Blewitt "Alex.Blewitt@ioshq.com" for his + valuable comments. He was the first to observe that finding Strings + in a hash table was an expensive operation. + + This change will require some recoding on your part. See the FAQ + for more details. + +Modified the force in Log and CGULog method to use a byte[] buffer + instead of a StringBuffer. The old code was clearer but the new one + is at least 25% faster. + + Add regression testing. + +We now enforce a policy where the OutputStream set by + setOutputStream is a user managed resource whereas the OutputStream + opened using setLogFile is the Log class' responsibility. + + The setLogFile method now closes any previous OutputStream if only + if opened through setLogFile. If the previous OutputStream was + opened by the user and set through setOutputStream the previous + OutputStream is untouched. + + Similarly, setOutputStream will close any previous OutputStream if + and only if it was opened using setLogFile. + + + Add a new method logOutputStreamExists to the Log class allowing + the programmer to check if there is already an opened stream before + trying to set a new one. A stream can be opened as a byproduct of + reading the configuration file. + +Changed the behavior of the (private) Log.Append method in case of + failure to write to the OutputStream. + + Previously, in case of failure, we reverted to System.err. Now, we + emit a warning message and discard all future log messages. The + new behavior is consistent with our current unreliable logging + semantics. The change prevents an otherwise functional program + from failing because the terminal is flooded with logging messages. + +Renamed the iLog to ILog to remain consistent with our class naming + scheme. The initial intention was to add ILog and deprecate + iLog. However, I am running CVS on a fat16 partition, causing + serious problems when files differ only in case. + +Corrected a bug where the LogFileName was not remembered. Thanks to + Jens for signaling this bug. + + + +Now the programmer can choose to truncate the log file instead of + always appending to it. This functionality was first requested and + intially implemented by "Jens Uwe Pipka" jens.pipka@gmx.de. + +setLogFile now opens the requested file instead of having the + Append function open it later. Cleaned up some related code in the + Append function. Although nobody has requested it, there is still + no method to close the log file. This is harder to implement + reliably than it sounds. + +Simplified setLogOutputStream so that it does no longer return the + previously set OutputStream. + + + + + +Joe Walker (joe@eireneh.com) observed that the + LogCreationManager.getSingleton mechanism was cumbersome. There is + now a new class iLog (indirect Log) which hides the need to call + getSingleton. Performance testing on my 233Mhz Thinkpad shows that + this indirection has small performance impact on non-logged calls + in the order of 40 nanoseconds. The impact on logged calls is + negligible. + + Add a jar file to the distribution. The jar file contains only + the files you would need to use log but not other classes needed + for testing nor examples. + +Corrected a bug where CGUNOPLog was not integrated to the Makefile. + + Add new public methods isDebugEnabled and isInfoEnabled to allow + programmers to check whether a debug/info statement will be logged + without incurring the cost of message parameter construction. This + addition was suggested by Luke Blanshard Luke@quiq.com. + +Renamed the private method evaluate to isEnabled. Also made it + final with no apparent speed gains. In addition, made the + Log.force method public. + +New syntactic sugar debug, ..., emerg, methods to log objects. + +Modified the interface to deal with Throwables and not just + Exceptions. My thanks to Luke Blanshard for signaling this "bug". + + Add more tests to the LogPerformance class. In particular, to + test the influence of indirect debug calls. + + Add a "make" mini-tutorial for those who want to modify the code. + +License updated to standard alphaWorks license allowing + modifications to source code. However, this license explicitly + requires that modifications be communicated back to alphaWorks. + + + + +Initial availability on alphaWorks. Refer to the FAQ for the lineage of the package. + + + diff --git a/src/main/java/org/apache/log4j/Appender.java b/src/main/java/org/apache/log4j/Appender.java index ae7405edcb..42ca4b8725 100644 --- a/src/main/java/org/apache/log4j/Appender.java +++ b/src/main/java/org/apache/log4j/Appender.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,120 +17,126 @@ package org.apache.log4j; -import org.apache.log4j.spi.Component; import org.apache.log4j.spi.Filter; -import org.apache.log4j.spi.LoggerRepository; +import org.apache.log4j.spi.ErrorHandler; import org.apache.log4j.spi.LoggingEvent; - /** - * Implement this interface for your own strategies for outputting log - * statements. - * - * @author Ceki Gülcü - */ -public interface Appender extends Component { + Implement this interface for your own strategies for outputting log + statements. + + @author Ceki Gülcü +*/ +public interface Appender { + /** - * Add a filter to the end of the filter list. - * - * @since 0.9.0 + Add a filter to the end of the filter list. + + @since 0.9.0 */ void addFilter(Filter newFilter); /** - * Returns the head Filter. The Filters are organized in a linked list and - * so all Filters on this Appender are available through the result. - * - * @return the head Filter or null, if no Filters are present - * - * @since 1.1 - */ - public Filter getFilter(); + Returns the head Filter. The Filters are organized in a linked list + and so all Filters on this Appender are available through the result. + + @return the head Filter or null, if no Filters are present + @since 1.1 + */ + public + Filter getFilter(); /** - * Clear the list of filters by removing all the filters in it. - * - * @since 0.9.0 + Clear the list of filters by removing all the filters in it. + + @since 0.9.0 */ - public void clearFilters(); + public + void clearFilters(); /** - * Release any resources allocated within the appender such as file handles, - * network connections, etc. - * - *

- * It is a programming error to append to a closed appender. - *

- * - * @since 0.8.4 - */ - public void close(); + Release any resources allocated within the appender such as file + handles, network connections, etc. - /** - * Log in Appender specific way. When appropriate, Loggers will - * call the doAppend method of appender implementations in - * order to log. - */ - public void doAppend(LoggingEvent event); +

It is a programming error to append to a closed appender. + @since 0.8.4 + */ + public + void close(); + /** - * Get the name of this appender. The name uniquely identifies the appender. - */ - public String getName(); + Log in Appender specific way. When appropriate, + Loggers will call the doAppend method of appender + implementations in order to log. */ + public + void doAppend(LoggingEvent event); + /** - * Set the {@link org.apache.log4j.spi.ErrorHandler} for this appender. - * - * @since 0.9.0 - * @deprecated As of 1.3 - */ - public void setErrorHandler(org.apache.log4j.spi.ErrorHandler errorHandler); + Get the name of this appender. + @return name, may be null.*/ + public + String getName(); + /** - * Returns the {@link org.apache.log4j.spi.ErrorHandler} for this appender. - * - * @since 1.1 - * @deprecated As of 1.3 + Set the {@link ErrorHandler} for this appender. + + @since 0.9.0 */ - public org.apache.log4j.spi.ErrorHandler getErrorHandler(); + public + void setErrorHandler(ErrorHandler errorHandler); /** - * Set the {@link Layout} for this appender. - * - * @since 0.8.1 + Returns the {@link ErrorHandler} for this appender. + + @since 1.1 */ - public void setLayout(Layout layout); + public + ErrorHandler getErrorHandler(); /** - * Returns this appenders layout. - * - * @since 1.1 - */ - public Layout getLayout(); + Set the {@link Layout} for this appender. + + @since 0.8.1 + */ + public + void setLayout(Layout layout); /** - * Set the name of this appender. The name is used by other components to - * identify this appender. - * - * @since 0.8.1 - */ - public void setName(String name); + Returns this appenders layout. + + @since 1.1 + */ + public + Layout getLayout(); - /** - Configurators call this method to determine if the appender - requires a layout. If this method returns true, - meaning that layout is required, then the configurator will - configure an layout using the configuration information at its - disposal. If this method returns false, meaning that - a layout is not required, then layout configuration will be - skipped even if there is available layout configuration - information at the disposal of the configurator.. - -

In the rather exceptional case, where the appender - implementation admits a layout but can also work without it, then - the appender should return true. - - @since 0.8.4 */ - public - boolean requiresLayout(); + + /** + Set the name of this appender. The name is used by other + components to identify this appender. + + @since 0.8.1 + */ + public + void setName(String name); + + /** + Configurators call this method to determine if the appender + requires a layout. If this method returns true, + meaning that layout is required, then the configurator will + configure an layout using the configuration information at its + disposal. If this method returns false, meaning that + a layout is not required, then layout configuration will be + skipped even if there is available layout configuration + information at the disposal of the configurator.. + +

In the rather exceptional case, where the appender + implementation admits a layout but can also work without it, then + the appender should return true. + + @since 0.8.4 */ + public + boolean requiresLayout(); } diff --git a/src/main/java/org/apache/log4j/AppenderSkeleton.java b/src/main/java/org/apache/log4j/AppenderSkeleton.java index 1ff4b279bb..5a98c84dad 100644 --- a/src/main/java/org/apache/log4j/AppenderSkeleton.java +++ b/src/main/java/org/apache/log4j/AppenderSkeleton.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,336 +17,289 @@ package org.apache.log4j; -import org.apache.log4j.Layout; -import org.apache.log4j.spi.ComponentBase; import org.apache.log4j.spi.Filter; -import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.spi.ErrorHandler; import org.apache.log4j.spi.OptionHandler; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.helpers.OnlyOnceErrorHandler; +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. - * - * @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 - */ -public abstract class AppenderSkeleton extends ComponentBase implements Appender, OptionHandler { - - /** - * The layout variable does not need to be set if the appender - * implementation has its own layout. - */ + * @author Ceki Gülcü + * */ +public abstract class AppenderSkeleton implements Appender, OptionHandler { + + /** The layout variable does not need to be set if the appender + implementation has its own layout. */ protected Layout layout; - /** - * Appenders are named. - */ + /** Appenders are named. */ protected String name; /** - * There is no level threshold filtering by default. - */ + There is no level threshold filtering by default. */ protected Priority threshold; - /** - * It is assumed and enforced that errorHandler is never null. - * - * @deprecated as of 1.3 - */ - protected org.apache.log4j.spi.ErrorHandler errorHandler = new org.apache.log4j.helpers.OnlyOnceErrorHandler(); + /** + It is assumed and enforced that errorHandler is never null. + */ + protected ErrorHandler errorHandler = new OnlyOnceErrorHandler(); - /** - * The first filter in the filter chain. Set to null initially. - */ + /** The first filter in the filter chain. Set to null + initially. */ protected Filter headFilter; - - /** - * The last filter in the filter chain. - */ + /** The last filter in the filter chain. */ protected Filter tailFilter; /** - * Is this appender closed? + Is this appender closed? */ protected boolean closed = false; - /** - * Is the appender ready for action. - */ - protected boolean active; - - /** - * The guard prevents an appender from repeatedly calling its own doAppend - * method. - */ - private boolean guard = false; + /** + * Create new instance. + */ + public AppenderSkeleton() { + super(); + } - /** - * Construct an AppenderSkeleton. - * - * @deprecated Provided for compatibility, migrate to AppenderSkeleton(boolean) - * to indicate whether appender is ready upon construction. - * - */ - public AppenderSkeleton() { - active = true; - } + /** + * Create new instance. + * Provided for compatibility with log4j 1.3. + * + * @param isActive true if appender is ready for use upon construction. + * Not used in log4j 1.2.x. + * @since 1.2.15 + */ + protected AppenderSkeleton(final boolean isActive) { + super(); + } -/** - * Construct an AppenderSkeleton. - * - * @param isActive true if appender is ready for use upon construction. - */ - protected AppenderSkeleton(final boolean isActive) { - active = isActive; - } /** - * Called to configure appender for use after configuration. - * - */ - public void activateOptions() { - this.active = true; + Derived appenders should override this method if option structure + requires it. */ + public + void activateOptions() { } - + /** - * Add a filter to end of the filter list. - * - * @since 0.9.0 + Add a filter to end of the filter list. + + @since 0.9.0 */ - public void addFilter(Filter newFilter) { - if (headFilter == null) { - headFilter = newFilter; - tailFilter = newFilter; + public + void addFilter(Filter newFilter) { + if(headFilter == null) { + headFilter = tailFilter = newFilter; } else { tailFilter.setNext(newFilter); - tailFilter = newFilter; + tailFilter = newFilter; } } /** - * Subclasses of AppenderSkeleton should implement this method - * to perform actual logging. See also {@link #doAppend - * AppenderSkeleton.doAppend} method. - * - * @since 0.9.0 - */ - protected abstract void append(LoggingEvent event); + Subclasses of AppenderSkeleton should implement this + method to perform actual logging. See also {@link #doAppend + AppenderSkeleton.doAppend} method. + + @since 0.9.0 + */ + abstract + protected + void append(LoggingEvent event); + /** - * Clear the filters chain. - * - * @since 0.9.0 - */ - public void clearFilters() { - headFilter = null; - tailFilter = null; + Clear the filters chain. + + @since 0.9.0 */ + public + void clearFilters() { + headFilter = tailFilter = null; } /** - * Finalize this appender by calling the derived class' close - * method. - * - * @since 0.8.4 - */ - public void finalize() { + Finalize this appender by calling the derived class' + close method. + + @since 0.8.4 */ + public + void finalize() { // An appender might be closed then garbage collected. There is no // point in closing twice. - if (this.closed) { - return; + if(this.closed) { + return; } - getLogger().debug("Finalizing appender named [{}].", name); + LogLog.debug("Finalizing appender named ["+name+"]."); close(); } - /** - * Return the hardcoded OnlyOnceErrorHandler for this Appender. - * ErrorHandlers are no longer utilized as of version 1.3. - * - * @since 0.9.0 - * @deprecated As of 1.3 - */ - public org.apache.log4j.spi.ErrorHandler getErrorHandler() { + + /** + Return the currently set {@link ErrorHandler} for this + Appender. + + @since 0.9.0 */ + public + ErrorHandler getErrorHandler() { return this.errorHandler; } + /** - * Returns the head Filter. - * - * @since 1.1 - */ - public Filter getFilter() { + Returns the head Filter. + + @since 1.1 + */ + public + Filter getFilter() { return headFilter; } - /** - * Return the first filter in the filter chain for this Appender. The return - * value may be null if no is filter is set. - */ - public final Filter getFirstFilter() { + /** + Return the first filter in the filter chain for this + Appender. The return value may be null if no is + filter is set. + + */ + public + final + Filter getFirstFilter() { return headFilter; } /** - * Returns the layout of this appender. The value may be null. - */ - public Layout getLayout() { + Returns the layout of this appender. The value may be null. + */ + public + Layout getLayout() { return layout; } + /** - * Returns the name of this appender. + Returns the name of this appender. + @return name, may be null. */ - public final String getName() { + public + final + String getName() { return this.name; } /** - * Returns this appenders threshold level. See the {@link #setThreshold} - * method for the meaning of this option. - * - * @since 1.1 - */ - public Priority getThreshold() { + Returns this appenders threshold level. See the {@link + #setThreshold} method for the meaning of this option. + + @since 1.1 */ + public + Priority getThreshold() { return threshold; } + /** - * Check whether the message level is below the appender's threshold. If - * there is no threshold set, then the return value is always - * true. - * @deprecated - */ - public boolean isAsSevereAsThreshold(final Priority level) { - return ((threshold == null) || level.isGreaterOrEqual(threshold)); + Check whether the message level is below the appender's + threshold. If there is no threshold set, then the return value is + always true. + + */ + public + boolean isAsSevereAsThreshold(Priority priority) { + return ((threshold == null) || priority.isGreaterOrEqual(threshold)); } - /** - * Check whether the message level is below the appender's threshold. If - * there is no threshold set, then the return value is always - * true. - */ - public boolean isAsSevereAsThreshold(final Level level) { - return ((threshold == null) || level.isGreaterOrEqual(threshold)); - } /** - * 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) { - // WARNING: The guard check MUST be the first statement in the - // doAppend() 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) { + if(closed) { + LogLog.error("Attempted to append to closed appender named ["+name+"]."); + return; + } - // prevent re-entry. - if (guard) { + if(!isAsSevereAsThreshold(event.getLevel())) { return; } - try { - guard = true; - - if (this.closed) { - getNonFloodingLogger().error( - "Attempted to append to closed appender named [{}].", name); - return; - } - - if (!this.active) { - getNonFloodingLogger().error( - "Attempted to log with inactive appender named [{}].", name); - return; - } - - if (!isAsSevereAsThreshold(event.getLevel())) { - return; - } - - Filter f = this.headFilter; - -FILTER_LOOP: - while (f != null) { - switch (f.decide(event)) { - case Filter.DENY: - return; - - case Filter.ACCEPT: - break FILTER_LOOP; - - case Filter.NEUTRAL: - f = f.getNext(); - } + Filter f = this.headFilter; + + FILTER_LOOP: + while(f != null) { + switch(f.decide(event)) { + case Filter.DENY: return; + case Filter.ACCEPT: break FILTER_LOOP; + case Filter.NEUTRAL: f = f.getNext(); } - - this.append(event); - } finally { - guard = false; } + + this.append(event); } - /** - * Returns true if this appender instance is closed. - * @since 1.3 - */ - public boolean isClosed() { - return closed; - } - - /** - * Returns true if this appender is working order. - * @since 1.3 - */ - public boolean isActive() { - // an appender can be active only if it is not closed - return (active && !closed); + /** + Set the {@link ErrorHandler} for this Appender. + @since 0.9.0 + */ + public + synchronized + void setErrorHandler(ErrorHandler eh) { + if(eh == null) { + // We do not throw exception here since the cause is probably a + // bad config file. + LogLog.warn("You have tried to set a null error-handler."); + } else { + this.errorHandler = eh; + } } /** - * Ignored as of 1.3 - * - * @since 0.9.0 - * @deprecated As of 1.3 - */ - public void setErrorHandler(org.apache.log4j.spi.ErrorHandler eh) { - ; //ignore - } - - /** - * Set the layout for this appender. Note that some appenders have their own - * (fixed) layouts or do not use one. For example, the {@link - * org.apache.log4j.net.SocketAppender} ignores the layout set here. - */ - public void setLayout(Layout layout) { + Set the layout for this appender. Note that some appenders have + their own (fixed) layouts or do not use one. For example, the + {@link org.apache.log4j.net.SocketAppender} ignores the layout set + here. + */ + public + void setLayout(Layout layout) { this.layout = layout; } + /** - * Set the name of this Appender. + Set the name of this Appender. */ - public void setName(String name) { + public + void setName(String name) { this.name = name; } + /** - * Set the threshold level. All log events with lower level than the - * threshold level are ignored by the appender. - * - *

- * In configuration files this option is specified by setting the value of - * the Threshold option to a level string, such as "DEBUG", "INFO" - * and so on. - *

- * - * @since 0.8.3 - */ - public void setThreshold(final Priority threshold) { + Set the threshold level. All log events with lower level + than the threshold level are ignored by the appender. + +

In configuration files this option is specified by setting the + value of the Threshold option to a level + string, such as "DEBUG", "INFO" and so on. + + @since 0.8.3 */ + public + void setThreshold(Priority threshold) { this.threshold = threshold; - } - + } } diff --git a/src/main/java/org/apache/log4j/AsyncAppender.java b/src/main/java/org/apache/log4j/AsyncAppender.java index d47edd45d6..214ffa7b9b 100644 --- a/src/main/java/org/apache/log4j/AsyncAppender.java +++ b/src/main/java/org/apache/log4j/AsyncAppender.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -18,12 +19,7 @@ // Thomas Tuft Muller package org.apache.log4j; -import org.apache.log4j.helpers.AppenderAttachableImpl; -import org.apache.log4j.spi.AppenderAttachable; -import org.apache.log4j.spi.LoggingEvent; - import java.text.MessageFormat; - import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; @@ -31,6 +27,10 @@ import java.util.List; import java.util.Map; +import org.apache.log4j.helpers.AppenderAttachableImpl; +import org.apache.log4j.spi.AppenderAttachable; +import org.apache.log4j.spi.LoggingEvent; + /** * The AsyncAppender lets users log events asynchronously. @@ -46,7 +46,7 @@ *

*

* Important note: The AsyncAppender can only be script - * configured using the {@link org.apache.log4j.joran.JoranConfigurator}. + * configured using the {@link org.apache.log4j.xml.DOMConfigurator}. *

* * @author Ceki Gülcü @@ -103,7 +103,6 @@ public class AsyncAppender extends AppenderSkeleton * Create new instance. */ public AsyncAppender() { - super(true); appenders = new AppenderAttachableImpl(); // @@ -119,7 +118,7 @@ public AsyncAppender() { // set the dispatcher priority to lowest possible value // dispatcher.setPriority(Thread.MIN_PRIORITY); - dispatcher.setName("Dispatcher-" + dispatcher.getName()); + dispatcher.setName("AsyncAppender-Dispatcher-" + dispatcher.getName()); dispatcher.start(); } @@ -150,13 +149,17 @@ public void append(final LoggingEvent event) { return; } - // extract all the thread dependent information now as later it will - // be too late. - event.prepareForDeferredProcessing(); - + // Set the NDC and thread name for the calling thread as these + // LoggingEvent fields were not set at event creation time. + event.getNDC(); + event.getThreadName(); + // Get a copy of this thread's MDC. + event.getMDCCopy(); if (locationInfo) { event.getLocationInformation(); } + event.getRenderedMessage(); + event.getThrowableStrRep(); synchronized (buffer) { while (true) { @@ -239,7 +242,7 @@ public void close() { dispatcher.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); - getLogger().error( + org.apache.log4j.helpers.LogLog.error( "Got an InterruptedException while waiting for the " + "dispatcher to finish.", e); } @@ -396,6 +399,7 @@ public int getBufferSize() { * Sets whether appender should wait if there is no * space available in the event buffer or immediately return. * + * @since 1.2.14 * @param value true if appender should wait until available space in buffer. */ public void setBlocking(final boolean value) { @@ -410,6 +414,7 @@ public void setBlocking(final boolean value) { * If false, messages will be counted by logger and a summary * message appended after the contents of the buffer have been appended. * + * @since 1.2.14 * @return true if calling thread will be blocked when buffer is full. */ public boolean getBlocking() { @@ -466,10 +471,10 @@ public LoggingEvent createEvent() { return new LoggingEvent( "org.apache.log4j.AsyncAppender.DONT_REPORT_LOCATION", - maxEvent.getLogger(), - maxEvent.getLevel(), - msg, - null); + Logger.getLogger(maxEvent.getLoggerName()), + maxEvent.getLevel(), + msg, + null); } } @@ -537,12 +542,12 @@ public void run() { // synchronized (buffer) { int bufferSize = buffer.size(); - isActive = !parent.isClosed(); + isActive = !parent.closed; while ((bufferSize == 0) && isActive) { buffer.wait(); bufferSize = buffer.size(); - isActive = !parent.isClosed(); + isActive = !parent.closed; } if (bufferSize > 0) { diff --git a/src/main/java/org/apache/log4j/BasicConfigurator.java b/src/main/java/org/apache/log4j/BasicConfigurator.java index db542d9920..2d859cf436 100644 --- a/src/main/java/org/apache/log4j/BasicConfigurator.java +++ b/src/main/java/org/apache/log4j/BasicConfigurator.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -14,10 +15,10 @@ * limitations under the License. */ - // Contibutors: "Luke Blanshard" // "Mark DONSZELMANN" // "Muly Oved" + package org.apache.log4j; @@ -31,6 +32,7 @@ @since 0.8.1 @author Ceki Gülcü */ public class BasicConfigurator { + protected BasicConfigurator() { } @@ -38,18 +40,21 @@ protected BasicConfigurator() { Add a {@link ConsoleAppender} that uses {@link PatternLayout} using the {@link PatternLayout#TTCC_CONVERSION_PATTERN} and prints to System.out to the root category. */ - public static void configure() { + static + public + void configure() { Logger root = Logger.getRootLogger(); - root.addAppender( - new ConsoleAppender( - new PatternLayout(PatternLayout.TTCC_CONVERSION_PATTERN))); + root.addAppender(new ConsoleAppender( + new PatternLayout(PatternLayout.TTCC_CONVERSION_PATTERN))); } /** Add appender to the root category. @param appender The appender to add to the root category. */ - public static void configure(Appender appender) { + static + public + void configure(Appender appender) { Logger root = Logger.getRootLogger(); root.addAppender(appender); } @@ -60,7 +65,9 @@ public static void configure(Appender appender) { Category.getDefaultHierarchy().resetConfiguration(). See {@link Hierarchy#resetConfiguration()} for more details. */ - public static void resetConfiguration() { + public + static + void resetConfiguration() { LogManager.resetConfiguration(); } } diff --git a/src/main/java/org/apache/log4j/Category.java b/src/main/java/org/apache/log4j/Category.java index 50159b35b5..9b304bc16a 100644 --- a/src/main/java/org/apache/log4j/Category.java +++ b/src/main/java/org/apache/log4j/Category.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -14,7 +15,6 @@ * limitations under the License. */ - // Contibutors: Alex Blewitt // Markus Oestreicher // Frank Hoering @@ -28,1462 +28,1069 @@ // Aaron Greenhouse // Beat Meier // Colin Sampaleanu -// Andy McBride + package org.apache.log4j; -import org.apache.log4j.helpers.AppenderAttachableImpl; -import org.apache.log4j.helpers.NullEnumeration; -import org.apache.log4j.helpers.ReaderWriterLock; import org.apache.log4j.spi.AppenderAttachable; -import org.apache.log4j.spi.LoggerRepository; import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.helpers.MessageFormatter; +import org.apache.log4j.spi.LoggerRepository; +import org.apache.log4j.spi.HierarchyEventListener; +import org.apache.log4j.helpers.NullEnumeration; +import org.apache.log4j.helpers.AppenderAttachableImpl; import java.util.Enumeration; import java.util.MissingResourceException; import java.util.ResourceBundle; +import java.util.Vector; /** - * This class has been deprecated and replaced by the - * {@link Logger}subclass. It will be kept around to - * preserve backward compatibility until such time as the Log4j team sees fit - * to remove it. - * - *

- * Logger is a subclass of Category, i.e. it extends Category. In - * other words, a logger is 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. - *

- * - *

- * For example, the following are all legal and will work as expected. - *

- *     // Deprecated form:
- *     Category cat = Category.getInstance("foo.bar")
- *     // Preferred form for retrieving loggers:
- *     Logger logger = Logger.getLogger("foo.bar")
- *  
- *

- * - *

- * The first form is deprecated and should be avoided. - *

- * - *

- * There is absolutely no need for new client code to use or refer to the - * Category class. Whenever possible, please avoid referring - * to it or using it. - *

- * - *

- * See the Short Manual for an - * introduction on this class. - *

- * - * @author Ceki Gülcü - * @author Anders Kristensen - * @author Yoav Shapira - */ -public class Category implements ULogger, AppenderAttachable { - /** - * The fully qualified name of the Category class. See also the getFQCN - * method. - */ + * This class has been deprecated and + * replaced by the {@link Logger} subclass. It + * will be kept around to preserve backward compatibility until mid + * 2003. + * + *

Logger is a subclass of Category, i.e. it extends + * Category. In other words, a logger is 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 never produce Category objects but + * only Logger instances. In order to preserve backward + * compatibility, methods that previously accepted category objects + * still continue to accept category objects. + * + *

For example, the following are all legal and will work as + * expected. + * +

+       // Deprecated form:
+       Category cat = Category.getInstance("foo.bar")
+   
+       // Preferred form for retrieving loggers:
+       Logger logger = Logger.getLogger("foo.bar")
+   
+ + *

The first form is deprecated and should be avoided. + * + *

There is absolutely no need for new client code to use or + * refer to the Category class. Whenever possible, + * please avoid referring to it or using it. + * + *

See the short manual for an + * introduction on this class. + *

+ * See the document entitled preparing + * for log4j 1.3 for a more detailed discussion. + * + * @author Ceki Gülcü + * @author Anders Kristensen + */ +public class Category implements AppenderAttachable { + + /** + The hierarchy where categories are attached to by default. + */ + //static + //public + //final Hierarchy defaultHierarchy = new Hierarchy(new + // RootCategory(Level.DEBUG)); + + /** + The name of this category. + */ + protected String name; + + /** + The assigned level of this category. The + level variable need not be assigned a value in + which case it is inherited form the hierarchy. */ + volatile protected Level level; + + /** + The parent of this category. All categories have at least one + ancestor which is the root category. */ + volatile protected Category parent; + + /** + The fully qualified name of the Category class. See also the + getFQCN method. */ private static final String FQCN = Category.class.getName(); - /** - * The hierarchy where categories are attached to by default. - */ - - /** - * The name of this category. - */ - protected String name; - - /** - * The assigned level of this category. The level variable - * need not be assigned a value in which case it is inherited form the - * hierarchy. - */ - protected volatile Level level; - - /** - * The parent of this category. All categories have at least one ancestor - * which is the root category. - */ - protected volatile Category parent; protected ResourceBundle resourceBundle; - protected ReaderWriterLock lock; // Categories need to know what Hierarchy they are in protected LoggerRepository repository; + + AppenderAttachableImpl aai; - /** - * Additivity is set to true by default, that is children inherit the - * appenders of their ancestors by default. If this variable is set to - * false then the appenders found in the ancestors of this - * category are not used. However, the children of this category will - * inherit its appenders, unless the children have their additivity flag - * set to false too. See the user manual for more details. - */ + /** Additivity is set to true by default, that is children inherit + the appenders of their ancestors by default. If this variable is + set to false then the appenders found in the + ancestors of this category are not used. However, the children + of this category will inherit its appenders, unless the children + have their additivity flag set to false too. See + the user manual for more details. */ protected boolean additive = true; /** - * This constructor created a new Category instance and sets - * its name. - * - *

- * It is intended to be used by sub-classes only. You should not create - * categories directly. - *

- * - * @param name The name of the category. - */ - protected Category(String name) { + This constructor created a new Category instance and + sets its name. + +

It is intended to be used by sub-classes only. You should not + create categories directly. + + @param name The name of the category. + */ + protected + Category(String name) { this.name = name; - lock = new ReaderWriterLock(); } /** - * Add newAppender to the list of appenders of this Category - * instance. - * - *

- * If newAppender is already in the list of appenders, then it - * won't be added again. - *

- */ - public void addAppender(Appender newAppender) { - // BEGIN - WRITE LOCK - lock.getWriteLock(); - try { - if (aai == null) { + Add newAppender to the list of appenders of this + Category instance. + +

If newAppender is already in the list of + appenders, then it won't be added again. + */ + synchronized + public + void addAppender(Appender newAppender) { + if(aai == null) { aai = new AppenderAttachableImpl(); } aai.addAppender(newAppender); - } finally { - lock.releaseWriteLock(); - } - // END - WRITE LOCK - - repository.fireAddAppenderEvent((Logger) this, newAppender); + repository.fireAddAppenderEvent(this, newAppender); } /** - * If assertion parameter is false, then logs - * msg as an {@link #error(Object) error} statement. - * - *

- * The assert method has been renamed to assertLog - * because assert is a language reserved word in JDK 1.4. - *

- * - * @param assertion - * @param msg The message to print if assertion is false. - * - * @since 1.2 - */ - public void assertLog(boolean assertion, String msg) { - if (!assertion) { - this.error(msg); + If assertion parameter is false, then + logs msg as an {@link #error(Object) error} statement. + +

The assert method has been renamed to + assertLog because assert is a language + reserved word in JDK 1.4. + + @param assertion + @param msg The message to print if assertion is + false. + + @since 1.2 */ + public + void assertLog(boolean assertion, String msg) { + if(!assertion) { + this.error(msg); } } + /** - * Call the appenders in the hierrachy starting at this. If no - * appenders could be found, emit a warning. - * - *

- * This method calls all the appenders inherited from the hierarchy - * circumventing any evaluation of whether to log or not to log the - * particular log request. - *

- * - * @param event the event to log. - */ - public void callAppenders(LoggingEvent event) { + Call the appenders in the hierrachy starting at + this. If no appenders could be found, emit a + warning. + +

This method calls all the appenders inherited from the + hierarchy circumventing any evaluation of whether to log or not + to log the particular log request. + + @param event the event to log. */ + public + void callAppenders(LoggingEvent event) { int writes = 0; - for (Category c = this; c != null; c = c.parent) { - // Protect against simultaneous writes operations such as - // addAppender, removeAppender,... - c.lock.getReadLock(); - try { - if (c.aai != null) { - writes += c.aai.appendLoopOnAppenders(event); - } - } finally { - c.lock.releaseReadLock(); - } - - if (!c.additive) { - break; - } + for(Category c = this; c != null; c=c.parent) { + // Protected against simultaneous call to addAppender, removeAppender,... + synchronized(c) { + if(c.aai != null) { + writes += c.aai.appendLoopOnAppenders(event); + } + if(!c.additive) { + break; + } + } } - if (writes == 0) { - repository.emitNoAppenderWarning((Logger) this); + if(writes == 0) { + repository.emitNoAppenderWarning(this); } } /** - * Close all attached appenders implementing the AppenderAttachable - * interface. - * - * @since 1.0 - */ + Close all attached appenders implementing the AppenderAttachable + interface. + @since 1.0 + */ + synchronized void closeNestedAppenders() { Enumeration enumeration = this.getAllAppenders(); - - if (enumeration != null) { - while (enumeration.hasMoreElements()) { - Appender a = (Appender) enumeration.nextElement(); - - if (a instanceof AppenderAttachable) { - a.close(); - } + if(enumeration != null) { + while(enumeration.hasMoreElements()) { + Appender a = (Appender) enumeration.nextElement(); + if(a instanceof AppenderAttachable) { + a.close(); + } } } } - /** - * Log a message object with the {@link Level#DEBUG DEBUG} level. - * - *

- * This method first checks if this category is DEBUG enabled - * by comparing the level of this category with the {@link Level#DEBUG - * DEBUG} level. If this category is DEBUG enabled, then it - * converts the message object (passed as parameter) to a string by - * invoking the appropriate {@link org.apache.log4j.or.ObjectRenderer}. It - * then proceeds to call all the registered appenders in this category and - * also higher in the hierarchy depending on the value of the additivity - * flag. - *

- * - *

- * WARNING Note that passing a {@link Throwable} to this method will - * print the name of the Throwable but no stack trace. To - * print a stack trace use the {@link #debug(Object, Throwable)} form - * instead. - *

- * - * @param message the message object to log. - */ - public void debug(Object message) { - if (repository.isDisabled(Level.DEBUG_INT)) { - return; - } + Log a message object with the {@link Level#DEBUG DEBUG} level. - if (Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, Level.DEBUG, message, null); - } - } +

This method first checks if this category is DEBUG + enabled by comparing the level of this category with the {@link + Level#DEBUG DEBUG} level. If this category is + DEBUG enabled, then it converts the message object + (passed as parameter) to a string by invoking the appropriate + {@link org.apache.log4j.or.ObjectRenderer}. It then proceeds to call all the + registered appenders in this category and also higher in the + hierarchy depending on the value of the additivity flag. - /** - * Log a message object with the DEBUG level including the - * stack trace of the {@link Throwable}t passed as parameter. - * - *

- * See {@link #debug(Object)} form for more detailed information. - *

- * - * @param message the message object to log. - * @param t the exception to log, including its stack trace. - */ - public void debug(Object message, Throwable t) { - if (repository.isDisabled(Level.DEBUG_INT)) { - return; - } +

WARNING Note that passing a {@link Throwable} to this + method will print the name of the Throwable but no + stack trace. To print a stack trace use the {@link #debug(Object, + Throwable)} form instead. - if (Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, Level.DEBUG, message, t); - } - } - - /** - * Log a message with the DEBUG level with message formatting - * done according to the value of messagePattern and - * arg parameters. - *

- * 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 messagePattern. - * @since 1.3 - */ - 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 DEBUG level with message formatting - * done according to the messagePattern and the arguments arg1 and arg2. - *

- * 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.3 - */ - public void debug(String messagePattern, Object arg1, Object arg2) { - if (repository.isDisabled(Level.DEBUG_INT)) { - return; + @param message the message object to log. */ + public + void debug(Object message) { + 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); + if(Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, Level.DEBUG, message, null); } } - - /** - * Check whether this category is enabled for the ERROR Level. See also - * {@link #isDebugEnabled()}. - * - * @return boolean - true if this category is enabled for level - * ERROR, false otherwise. - */ - public boolean isErrorEnabled() { - if (repository.isDisabled(Level.ERROR_INT)) { - return false; - } - return Level.ERROR.isGreaterOrEqual(this.getEffectiveLevel()); - } /** - * Log a message object with the {@link Level#ERROR ERROR} Level. - * - *

- * This method first checks if this category is ERROR enabled - * by comparing the level of this category with {@link Level#ERROR ERROR} - * Level. If this category is ERROR enabled, then it converts - * the message object passed as parameter to a string by invoking the - * appropriate {@link org.apache.log4j.or.ObjectRenderer}. It proceeds to - * call all the registered appenders in this category and also higher in - * the hierarchy depending on the value of the additivity flag. - *

- * - *

- * WARNING Note that passing a {@link Throwable} to this method will - * print the name of the Throwable but no stack trace. To - * print a stack trace use the {@link #error(Object, Throwable)} form - * instead. - *

- * - * @param message the message object to log - */ - public void error(Object message) { - if (repository.isDisabled(Level.ERROR_INT)) { - return; - } + Log a message object with the DEBUG level including + the stack trace of the {@link Throwable} t passed as + parameter. - if (Level.ERROR.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, Level.ERROR, message, null); - } - } +

See {@link #debug(Object)} form for more detailed information. - /** - * Log a message object with the ERROR level including the - * stack trace of the {@link Throwable}t passed as parameter. - * - *

- * See {@link #error(Object)} form for more detailed information. - *

- * - * @param message the message object to log. - * @param t the exception to log, including its stack trace. - */ - public void error(Object message, Throwable t) { - if (repository.isDisabled(Level.ERROR_INT)) { - return; + @param message the message object to log. + @param t the exception to log, including its stack trace. */ + public + void debug(Object message, Throwable t) { + if(repository.isDisabled(Level.DEBUG_INT)) { + return; } - - if (Level.ERROR.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, Level.ERROR, message, t); + if(Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, Level.DEBUG, message, t); } } /** - * Log a message with the ERROR level with message formatting - * done according to the value of messagePattern and - * arg parameters. - *

- * 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 messagePattern. - * @since 1.3 - */ - public void error(Object messagePattern, Object arg) { - if (repository.isDisabled(Level.ERROR_INT)) { - return; - } + Log a message object with the {@link Level#ERROR ERROR} Level. - 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); - } +

This method first checks if this category is ERROR + enabled by comparing the level of this category with {@link + Level#ERROR ERROR} Level. If this category is ERROR + enabled, then it converts the message object passed as parameter + to a string by invoking the appropriate {@link + org.apache.log4j.or.ObjectRenderer}. It proceeds to call all the + registered appenders in this category and also higher in the + hierarchy depending on the value of the additivity flag. + +

WARNING Note that passing a {@link Throwable} to this + method will print the name of the Throwable but no + stack trace. To print a stack trace use the {@link #error(Object, + Throwable)} form instead. + + @param message the message object to log */ + public + void error(Object message) { + if(repository.isDisabled(Level.ERROR_INT)) { + return; + } + if(Level.ERROR.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, Level.ERROR, message, null); } } - + /** - * Log a message with the ERROR level with message formatting - * done according to the messagePattern and the arguments arg1 and arg2. - *

- * 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.3 - */ - public void error(String messagePattern, Object arg1, Object arg2) { - if (repository.isDisabled(Level.ERROR_INT)) { - return; + Log a message object with the ERROR level including + the stack trace of the {@link Throwable} t passed as + parameter. + +

See {@link #error(Object)} form for more detailed information. + + @param message the message object to log. + @param t the exception to log, including its stack trace. */ + public + void error(Object message, Throwable t) { + 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); + if(Level.ERROR.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, Level.ERROR, message, t); } + } - + + /** - * If the named category exists (in the default hierarchy) then it returns a - * reference to the category, otherwise it returns null. - * - * @since 0.8.5 - * @deprecated Please use {@link LogManager#exists} instead. - */ - public static Logger exists(String name) { + If the named category exists (in the default hierarchy) then it + returns a reference to the category, otherwise it returns + null. + + @deprecated Please use {@link LogManager#exists} instead. + + @since 0.8.5 */ + public + static + Logger exists(String name) { return LogManager.exists(name); } /** - * Log a message object with the {@link Level#FATAL FATAL} Level. - * - *

- * This method first checks if this category is FATAL enabled - * by comparing the level of this category with {@link Level#FATAL FATAL} - * Level. If the category is FATAL enabled, then it converts - * the message object passed as parameter to a string by invoking the - * appropriate {@link org.apache.log4j.or.ObjectRenderer}. It proceeds to - * call all the registered appenders in this category and also higher in - * the hierarchy depending on the value of the additivity flag. - *

- * - *

- * WARNING Note that passing a {@link Throwable} to this method will - * print the name of the Throwable but no stack trace. To print a stack - * trace use the {@link #fatal(Object, Throwable)} form instead. - *

- * - * @param message the message object to log - */ - public void fatal(Object message) { - if (repository.isDisabled(Level.FATAL_INT)) { - return; - } + Log a message object with the {@link Level#FATAL FATAL} Level. - if (Level.FATAL.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, Level.FATAL, message, null); - } - } - - /** - * Log a message with the FATAL level with message formatting - * done according to the value of messagePattern and - * arg parameters. - *

- * 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 messagePattern. - * @since 1.3 - */ - public void fatal(Object messagePattern, Object arg) { - if (repository.isDisabled(Level.FATAL_INT)) { - return; - } +

This method first checks if this category is FATAL + enabled by comparing the level of this category with {@link + Level#FATAL FATAL} Level. If the category is FATAL + enabled, then it converts the message object passed as parameter + to a string by invoking the appropriate + {@link org.apache.log4j.or.ObjectRenderer}. It + proceeds to call all the registered appenders in this category and + also higher in the hierarchy depending on the value of the + additivity flag. - if (Level.FATAL.isGreaterOrEqual(this.getEffectiveLevel())) { - if (messagePattern instanceof String){ - String msgStr = (String) messagePattern; - msgStr = MessageFormatter.format(msgStr, arg); - forcedLog(FQCN, Level.FATAL, 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.FATAL, messagePattern, null); - } +

WARNING Note that passing a {@link Throwable} to this + method will print the name of the Throwable but no stack trace. To + print a stack trace use the {@link #fatal(Object, Throwable)} form + instead. + + @param message the message object to log */ + public + void fatal(Object message) { + if(repository.isDisabled(Level.FATAL_INT)) { + return; + } + if(Level.FATAL.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, Level.FATAL, message, null); } } /** - * Log a message object with the FATAL level including the - * stack trace of the {@link Throwable}t passed as parameter. - * - *

- * See {@link #fatal(Object)} for more detailed information. - *

- * - * @param message the message object to log. - * @param t the exception to log, including its stack trace. - */ - public void fatal(Object message, Throwable t) { - if (repository.isDisabled(Level.FATAL_INT)) { - return; - } + Log a message object with the FATAL level including + the stack trace of the {@link Throwable} t passed as + parameter. + +

See {@link #fatal(Object)} for more detailed information. - if (Level.FATAL.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, Level.FATAL, message, t); + @param message the message object to log. + @param t the exception to log, including its stack trace. */ + public + void fatal(Object message, Throwable t) { + if(repository.isDisabled(Level.FATAL_INT)) { + return; + } + if(Level.FATAL.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, Level.FATAL, message, t); } } + /** - * This method creates a new logging event and logs the event without - * further checks. - */ - protected void forcedLog( - String fqcn, Priority level, Object message, Throwable t) { - callAppenders(new LoggingEvent(fqcn, (Logger) this, level, message, t)); + This method creates a new logging event and logs the event + without further checks. */ + protected + void forcedLog(String fqcn, Priority level, Object message, Throwable t) { + callAppenders(new LoggingEvent(fqcn, this, level, message, t)); } + /** - * Get the additivity flag for this Category instance. - */ - public boolean getAdditivity() { + Get the additivity flag for this Category instance. + */ + public + boolean getAdditivity() { return additive; } /** - * Get the appenders contained in this category as an {@link Enumeration}. - * If no appenders can be found, then a {@link NullEnumeration} is - * returned. - * - * @return Enumeration An enumeration of the appenders in this category. - */ - public Enumeration getAllAppenders() { - Enumeration result; - lock.getReadLock(); - try { - if (aai == null) { - result = NullEnumeration.getInstance(); + Get the appenders contained in this category as an {@link + Enumeration}. If no appenders can be found, then a {@link NullEnumeration} + is returned. + + @return Enumeration An enumeration of the appenders in this category. */ + synchronized + public + Enumeration getAllAppenders() { + if(aai == null) { + return NullEnumeration.getInstance(); } else { - result = aai.getAllAppenders(); - } - } finally { - lock.releaseReadLock(); + return aai.getAllAppenders(); } - return result; } /** - * Look for the appender named as name. - * - *

- * Return the appender with that name if in the list. Return - * null otherwise. - *

- */ - public Appender getAppender(String name) { - Appender result; - - lock.getReadLock(); - try { - if ((aai == null) || (name == null)) { - result = null; - } else { - result = aai.getAppender(name); - } - } finally { - lock.releaseReadLock(); - } - - return result; + Look for the appender named as name. + +

Return the appender with that name if in the list. Return + null otherwise. */ + synchronized + public + Appender getAppender(String name) { + if(aai == null || name == null) { + return null; + } + + return aai.getAppender(name); } /** - * Starting from this category, search the category hierarchy for a non-null - * level and return it. Otherwise, return the level of the root category. - * - *

- * The Category class is designed so that this method executes as quickly as - * possible. - *

+ Starting from this category, search the category hierarchy for a + non-null level and return it. Otherwise, return the level of the + root category. + +

The Category class is designed so that this method executes as + quickly as possible. */ - public Level getEffectiveLevel() { - for (Category c = this; c != null; c = c.parent) { - if (c.level != null) { + public + Level getEffectiveLevel() { + for(Category c = this; c != null; c=c.parent) { + if(c.level != null) { return c.level; - } } - + } return null; // If reached will cause an NullPointerException. } /** - * @deprecated Please use the the {@link #getEffectiveLevel} method instead. - */ - public Priority getChainedPriority() { - for (Category c = this; c != null; c = c.parent) { - if (c.level != null) { + * + * @deprecated Please use the the {@link #getEffectiveLevel} method + * instead. + * */ + public + Priority getChainedPriority() { + for(Category c = this; c != null; c=c.parent) { + if(c.level != null) { return c.level; - } } - + } return null; // If reached will cause an NullPointerException. } + /** - * Returns all the currently defined categories in the default hierarchy as - * an {@link java.util.Enumeration Enumeration}. - * - *

- * The root category is not included in the returned {@link - * Enumeration}. - *

- * - * @deprecated Please use {@link LogManager#getCurrentLoggers()} instead. - */ - public static Enumeration getCurrentCategories() { + Returns all the currently defined categories in the default + hierarchy as an {@link java.util.Enumeration Enumeration}. + +

The root category is not included in the returned + {@link Enumeration}. + + @deprecated Please use {@link LogManager#getCurrentLoggers()} instead. + */ + public + static + Enumeration getCurrentCategories() { return LogManager.getCurrentLoggers(); } + /** - * Return the default Hierarchy instance. - * - * @since 1.0 - * @deprecated Please use {@link LogManager#getLoggerRepository()} instead. + Return the default Hierarchy instance. + + @deprecated Please use {@link LogManager#getLoggerRepository()} instead. + + @since 1.0 */ - public static LoggerRepository getDefaultHierarchy() { + public + static + LoggerRepository getDefaultHierarchy() { return LogManager.getLoggerRepository(); } /** - * Return the the {@link Hierarchy} where this Category - * instance is attached. - * - * @since 1.1 - * @deprecated Please use {@link #getLoggerRepository} instead. - */ - public LoggerRepository getHierarchy() { + Return the the {@link Hierarchy} where this Category + instance is attached. + + @deprecated Please use {@link #getLoggerRepository} instead. + + @since 1.1 */ + public + LoggerRepository getHierarchy() { return repository; } /** - * Return the the {@link LoggerRepository} where this Category - * is attached. - * - * @since 1.2 - */ - public LoggerRepository getLoggerRepository() { + Return the the {@link LoggerRepository} where this + Category is attached. + + @since 1.2 */ + public + LoggerRepository getLoggerRepository() { return repository; } - /** - * @deprecated Please use the {@link Logger#getLogger(String)} method instead. - */ - public static Category getInstance(String name) { + + /** + * @deprecated Make sure to use {@link Logger#getLogger(String)} instead. + */ + public + static + Category getInstance(String name) { return LogManager.getLogger(name); } - /** - * @deprecated Please use {@link Logger#getLogger(Class)} instead. - */ - public static Category getInstance(Class clazz) { + /** + * @deprecated Please make sure to use {@link Logger#getLogger(Class)} instead. + */ + public + static + Category getInstance(Class clazz) { return LogManager.getLogger(clazz); } + /** - * Return the category name. - */ - public final String getName() { + Return the category name. */ + public + final + String getName() { return name; } + /** - * Returns the parent of this category. Note that the parent of a given - * category may change during the lifetime of the category. - * - *

- * The root category will return null. - *

- * - * @since 1.2 - */ - public final Category getParent() { + Returns the parent of this category. Note that the parent of a + given category may change during the lifetime of the category. + +

The root category will return null. + + @since 1.2 + */ + final + public + Category getParent() { return this.parent; } + /** - * Returns the assigned {@link Level}, if any, for this Category. - * - * @return Level - the assigned Level, can be null. - */ - public final Level getLevel() { + Returns the assigned {@link Level}, if any, for this Category. + + @return Level - the assigned Level, can be null. + */ + final + public + Level getLevel() { return this.level; } /** - * @deprecated Please use {@link #getLevel} instead. - */ - public final Level getPriority() { + @deprecated Please use {@link #getLevel} instead. + */ + final + public + Level getPriority() { return this.level; } + /** - * @deprecated Please use the {@link Logger#getRootLogger()} method instead. + * @deprecated Please use {@link Logger#getRootLogger()} instead. */ - public static final Category getRoot() { + final + public + static + Category getRoot() { return LogManager.getRootLogger(); } /** - * Return the inherited{@link ResourceBundle} for this category. - * - *

- * This method walks the hierarchy to find the appropriate resource bundle. - * It will return the resource bundle attached to the closest ancestor of - * this category, much like the way priorities are searched. In case there - * is no bundle in the hierarchy then null is returned. - *

- * - * @since 0.9.0 - */ - public ResourceBundle getResourceBundle() { - for (Category c = this; c != null; c = c.parent) { - if (c.resourceBundle != null) { + Return the inherited {@link ResourceBundle} for this + category. + +

This method walks the hierarchy to find the appropriate + resource bundle. It will return the resource bundle attached to + the closest ancestor of this category, much like the way + priorities are searched. In case there is no bundle in the + hierarchy then null is returned. + + @since 0.9.0 */ + public + ResourceBundle getResourceBundle() { + for(Category c = this; c != null; c=c.parent) { + if(c.resourceBundle != null) { return c.resourceBundle; - } } - + } // It might be the case that there is no resource bundle return null; } /** - * Returns the string resource coresponding to key in this - * category's inherited resource bundle. See also {@link - * #getResourceBundle}. - * - *

- * If the resource cannot be found, then an {@link #error error} message - * will be logged complaining about the missing resource. - *

- */ - protected String getResourceBundleString(String key) { - ResourceBundle rb = getResourceBundle(); + Returns the string resource coresponding to key in + this category's inherited resource bundle. See also {@link + #getResourceBundle}. +

If the resource cannot be found, then an {@link #error error} + message will be logged complaining about the missing resource. + */ + protected + String getResourceBundleString(String key) { + ResourceBundle rb = getResourceBundle(); // This is one of the rare cases where we can use logging in order // to report errors from within log4j. - if (rb == null) { + if(rb == null) { //if(!hierarchy.emittedNoResourceBundleWarning) { //error("No resource bundle has been set for category "+name); //hierarchy.emittedNoResourceBundleWarning = true; //} return null; - } else { + } + else { try { - return rb.getString(key); - } catch (MissingResourceException mre) { - error("No resource is associated with key \"" + key + "\"."); - - return null; + return rb.getString(key); + } + catch(MissingResourceException mre) { + error("No resource is associated with key \""+key+"\"."); + return null; } } } /** - * Log a message object with the {@link Level#INFO INFO} Level. - * - *

- * This method first checks if this category is INFO enabled by - * comparing the level of this category with {@link Level#INFO INFO} Level. - * If the category is INFO enabled, then it converts the - * message object passed as parameter to a string by invoking the - * appropriate {@link org.apache.log4j.or.ObjectRenderer}. It proceeds to - * call all the registered appenders in this category and also higher in - * the hierarchy depending on the value of the additivity flag. - *

- * - *

- * WARNING Note that passing a {@link Throwable} to this method will - * print the name of the Throwable but no stack trace. To print a stack - * trace use the {@link #info(Object, Throwable)} form instead. - *

- * - * @param message the message object to log - */ - public void info(Object message) { - if (repository.isDisabled(Level.INFO_INT)) { - return; - } + Log a message object with the {@link Level#INFO INFO} Level. - if (Level.INFO.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, Level.INFO, message, null); - } - } +

This method first checks if this category is INFO + enabled by comparing the level of this category with {@link + Level#INFO INFO} Level. If the category is INFO + enabled, then it converts the message object passed as parameter + to a string by invoking the appropriate + {@link org.apache.log4j.or.ObjectRenderer}. It + proceeds to call all the registered appenders in this category and + also higher in the hierarchy depending on the value of the + additivity flag. - /** - * Log a message with the INFO level with message formatting - * done according to the value of messagePattern and - * arg parameters. - *

- * 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 messagePattern. - * @since 1.3 - */ - public void info(Object messagePattern, Object arg) { - if (repository.isDisabled(Level.INFO_INT)) { - return; - } +

WARNING Note that passing a {@link Throwable} to this + method will print the name of the Throwable but no stack trace. To + print a stack trace use the {@link #info(Object, Throwable)} form + instead. - 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 INFO level with message formatting - * done according to the messagePattern and the arguments arg1 and arg2. - *

- * 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.3 - */ - 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 INFO level including the stack - * trace of the {@link Throwable}t passed as parameter. - * - *

- * See {@link #info(Object)} for more detailed information. - *

- * - * @param message the message object to log. - * @param t the exception to log, including its stack trace. - */ - public void info(Object message, Throwable t) { - if (repository.isDisabled(Level.INFO_INT)) { - return; + @param message the message object to log */ + public + void info(Object message) { + if(repository.isDisabled(Level.INFO_INT)) { + return; } - - if (Level.INFO.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, Level.INFO, message, t); + if(Level.INFO.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, Level.INFO, message, null); } } /** - * Is the appender passed as parameter attached to this category? - */ - public boolean isAttached(Appender appender) { - boolean result; + Log a message object with the INFO level including + the stack trace of the {@link Throwable} t passed as + parameter. - lock.getReadLock(); - try { - if ((appender == null) || (aai == null)) { - result = false; - } else { - result = aai.isAttached(appender); +

See {@link #info(Object)} for more detailed information. + + @param message the message object to log. + @param t the exception to log, including its stack trace. */ + public + void info(Object message, Throwable t) { + if(repository.isDisabled(Level.INFO_INT)) { + return; } - } finally { - lock.releaseReadLock(); + if(Level.INFO.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, Level.INFO, message, t); } - - return result; } /** - * Check whether this category is enabled for the DEBUG Level. - * - *

- * This function is intended to lessen the computational cost of disabled - * log debug statements. - *

- * - *

- * For some cat Category object, when you write, - *

-   *      cat.debug("This is entry number: " + i );
-   *  
- *

- * - *

- * You incur the cost constructing the message, concatenatiion in this case, - * regardless of whether the message is logged or not. - *

- * - *

- * If you are worried about speed, then you should write - *

-   *          if(cat.isDebugEnabled()) {
-   *            cat.debug("This is entry number: " + i );
-   *          }
-   *  
- *

- * - *

- * This way you will not incur the cost of parameter construction if - * debugging is disabled for cat. On the other hand, if the - * cat is debug enabled, you will incur the cost of evaluating - * whether the category is debug enabled twice. Once in - * isDebugEnabled and once in the debug. This is - * an insignificant overhead since evaluating a category takes about 1%% of - * the time it takes to actually log. - *

- * - * @return boolean - true if this category is debug enabled, - * false otherwise. + Is the appender passed as parameter attached to this category? */ - public boolean isDebugEnabled() { - if (repository.isDisabled(Level.DEBUG_INT)) { - return false; + public + boolean isAttached(Appender appender) { + if(appender == null || aai == null) { + return false; + } else { + return aai.isAttached(appender); + } + } + + /** + * Check whether this category is enabled for the DEBUG + * Level. + * + *

This function is intended to lessen the computational cost of + * disabled log debug statements. + * + *

For some cat Category object, when you write, + *

+    *      cat.debug("This is entry number: " + i );
+    *  
+ * + *

You incur the cost constructing the message, concatenatiion in + * this case, regardless of whether the message is logged or not. + * + *

If you are worried about speed, then you should write + *

+    * 	 if(cat.isDebugEnabled()) {
+    * 	   cat.debug("This is entry number: " + i );
+    * 	 }
+    *  
+ * + *

This way you will not incur the cost of parameter + * construction if debugging is disabled for cat. On + * the other hand, if the cat is debug enabled, you + * will incur the cost of evaluating whether the category is debug + * enabled twice. Once in isDebugEnabled and once in + * the debug. This is an insignificant overhead + * since evaluating a category takes about 1%% of the time it + * takes to actually log. + * + * @return boolean - true if this category is debug + * enabled, false otherwise. + * */ + public + boolean isDebugEnabled() { + if(repository.isDisabled( Level.DEBUG_INT)) { + return false; } - return Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel()); } /** - * Check whether this category is enabled for the TRACE Level. See also - * {@link #isDebugEnabled()}. - * - * @return boolean - true if this category is enabled for level - * TRACE, false otherwise. - */ - public boolean isTraceEnabled() { - if (repository.isDisabled(Level.TRACE_INT)) { - return false; - } + Check whether this category is enabled for a given {@link + Level} passed as parameter. - return Level.TRACE.isGreaterOrEqual(this.getEffectiveLevel()); - } + See also {@link #isDebugEnabled}. - /** - * Check whether this category is enabled for a given {@link Level} passed - * as parameter. See also {@link #isDebugEnabled()}. - * - * @return boolean True if this logger is enabled for level. - */ - public boolean isEnabledFor(Level level) { - if (repository.isDisabled(level.level)) { - return false; + @return boolean True if this category is enabled for level. + */ + public + boolean isEnabledFor(Priority level) { + if(repository.isDisabled(level.level)) { + return false; } - return level.isGreaterOrEqual(this.getEffectiveLevel()); } /** - * @deprecated Use the alternate form taking a parameter of type Level. - */ - public boolean isEnabledFor(Priority level) { - return isEnabledFor((Level) level); - } - - /** - * Check whether this category is enabled for the info Level. See also - * {@link #isDebugEnabled()}. - * - * @return boolean - true if this category is enabled for level - * info, false otherwise. - */ - public boolean isInfoEnabled() { - if (repository.isDisabled(Level.INFO_INT)) { - return false; - } + Check whether this category is enabled for the info Level. + See also {@link #isDebugEnabled}. + @return boolean - true if this category is enabled + for level info, false otherwise. + */ + public + boolean isInfoEnabled() { + if(repository.isDisabled(Level.INFO_INT)) { + return false; + } return Level.INFO.isGreaterOrEqual(this.getEffectiveLevel()); } - - /** - * Log a localized message. The user supplied parameter key is - * replaced by its localized version from the resource bundle. - * - * @see #setResourceBundle - * @since 0.8.4 - */ - public void l7dlog(final Priority level, String key, Throwable t) { - l7dlog(level, key, null, t); - } - /** - * Log a localized message. The user supplied parameter key is - * replaced by its localized version from the resource bundle. - * - * @see #setResourceBundle - * @since 1.3 - */ - public void l7dlog(final Priority level, String key) { - l7dlog(level, key, null, null); - } /** - * Log a localized and parameterized message. First, the user supplied - * key is searched in the resource bundle. Next, the resulting - * pattern is formatted using {@link - * java.text.MessageFormat#format(String,Object[])} method with the user - * supplied object array params. - * - * @since 0.8.4 - */ - public void l7dlog(Priority level, String key, Object[] params, Throwable t) { - l7dlog(FQCN, level, key, params, t); - } + Log a localized message. The user supplied parameter + key is replaced by its localized version from the + resource bundle. - /** - * Log a localized and parameterized message. First, the user supplied - * key is searched in the resource bundle. Next, the resulting - * pattern is formatted using {@link - * java.text.MessageFormat#format(String,Object[])} method with the user - * supplied object array params. - * - * @since 1.3 - */ - public void l7dlog(Priority level, String key, Object[] params) { - l7dlog(FQCN, level, key, params, null); - } + @see #setResourceBundle - /** - * @deprecated Use the form taking in a Level as a parameter. - */ - public void log(Priority level, Object message, Throwable t) { - log((Level) level, message, t); - } - - /** - * This generic form is intended to be used by wrappers. - */ - public void log(Level level, Object message, Throwable t) { - if (repository.isDisabled(level.level)) { + @since 0.8.4 */ + public + void l7dlog(Priority priority, String key, Throwable t) { + if(repository.isDisabled(priority.level)) { return; } - - if (level.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, level, message, t); + if(priority.isGreaterOrEqual(this.getEffectiveLevel())) { + String msg = getResourceBundleString(key); + // if message corresponding to 'key' could not be found in the + // resource bundle, then default to 'key'. + if(msg == null) { + msg = key; + } + forcedLog(FQCN, priority, msg, t); } } - - /** - * @deprecated Use the form taking in a Level as a parameter. - */ - public void log(Priority level, Object message) { - log((Level) level, message); - } - /** - * This generic form is intended to be used by wrappers. For the extraction - * of caller information, use the most generic form {@link #log( - String callerFQCN, Level level, Object message, Throwable t)}. - */ - public void log(Level level, Object message) { - if (repository.isDisabled(level.level)) { + Log a localized and parameterized message. First, the user + supplied key is searched in the resource + bundle. Next, the resulting pattern is formatted using + {@link java.text.MessageFormat#format(String,Object[])} method with the + user supplied object array params. + + @since 0.8.4 + */ + public + void l7dlog(Priority priority, String key, Object[] params, Throwable t) { + if(repository.isDisabled(priority.level)) { return; } - - if (level.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, level, message, null); + if(priority.isGreaterOrEqual(this.getEffectiveLevel())) { + String pattern = getResourceBundleString(key); + String msg; + if(pattern == null) { + msg = key; + } else { + msg = java.text.MessageFormat.format(pattern, params); + } + forcedLog(FQCN, priority, msg, t); } } /** - * This is the most generic printing method. It is intended to be invoked by - * wrapper classes. - * - * @param callerFQCN The wrapper class' fully qualified class name. - * @param level The level of the logging request. - * @param message The message of the logging request. - * @param t The throwable of the logging request, may be null. + This generic form is intended to be used by wrappers. */ - public void log( - String callerFQCN, Level level, Object message, Throwable t) { - if (repository.isDisabled(level.level)) { + public + void log(Priority priority, Object message, Throwable t) { + if(repository.isDisabled(priority.level)) { return; } - - if (level.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(callerFQCN, level, message, t); + if(priority.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, priority, message, t); } } - /** - * This is the most generic localized printing method. It is intended to be invoked by - * wrapper classes. - * - * @param callerFQCN The wrapper class' fully qualified class name. - * @param level The level of the logging request. - * @param key The key of the resource bundle message. - * @param param Format parameteres, if null will not be used. - * @param t The throwable of the logging request, may be null. - * - * @since 1.3 - */ - public void l7dlog( - String callerFQCN, Priority level, String key, Object[] params, Throwable t) - { - if (repository.isDisabled(level.level)) { + /** + This generic form is intended to be used by wrappers. + */ + public + void log(Priority priority, Object message) { + if(repository.isDisabled(priority.level)) { return; } + if(priority.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, priority, message, null); + } + } - if (level.isGreaterOrEqual(this.getEffectiveLevel())) { - String pattern = getResourceBundleString(key); - String msg; + /** - if (pattern == null) { - msg = key; - } else { - if (params != null) - msg = java.text.MessageFormat.format(pattern, params); - else - msg = pattern; - } + This is the most generic printing method. It is intended to be + invoked by wrapper classes. - forcedLog(callerFQCN, level, msg, t); + @param callerFQCN The wrapper class' fully qualified class name. + @param level The level of the logging request. + @param message The message of the logging request. + @param t The throwable of the logging request, may be null. */ + public + void log(String callerFQCN, Priority level, Object message, Throwable t) { + if(repository.isDisabled(level.level)) { + return; + } + if(level.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(callerFQCN, level, message, t); } } - - /** - * @deprecated Use the form taking in a Level as a parameter. - */ - public void log( - String callerFQCN, Priority level, Object message, Throwable t) { - log(callerFQCN, (Level) level, message, t); - } - - + /** + * LoggerRepository forgot the fireRemoveAppenderEvent method, + * if using the stock Hierarchy implementation, then call its fireRemove. + * Custom repositories can implement HierarchyEventListener if they + * want remove notifications. + * @param appender appender, may be null. + */ + private void fireRemoveAppenderEvent(final Appender appender) { + if (appender != null) { + if (repository instanceof Hierarchy) { + ((Hierarchy) repository).fireRemoveAppenderEvent(this, appender); + } else if (repository instanceof HierarchyEventListener) { + ((HierarchyEventListener) repository).removeAppenderEvent(this, appender); + } + } + } + /** - * Remove all previously added appenders from this Category instance. - *

Removed appenders are closed.

- *

This is useful when re-reading configuration information.

- */ - public void removeAllAppenders() { - lock.getWriteLock(); - try { - if (aai != null) { + Remove all previously added appenders from this Category + instance. + +

This is useful when re-reading configuration information. + */ + synchronized + public + void removeAllAppenders() { + if(aai != null) { + Vector appenders = new Vector(); + for (Enumeration iter = aai.getAllAppenders(); iter != null && iter.hasMoreElements();) { + appenders.add(iter.nextElement()); + } aai.removeAllAppenders(); + for(Enumeration iter = appenders.elements(); iter.hasMoreElements();) { + fireRemoveAppenderEvent((Appender) iter.nextElement()); + } aai = null; } - } finally { - lock.releaseWriteLock(); - } } + /** - * Remove the appender passed as parameter form the list of appenders. - * - *

Does not close the appender.

- * - * @since 0.8.2 - */ - public void removeAppender(Appender appender) { - lock.getWriteLock(); - try { - if ((appender == null) || (aai == null)) { - // Nothing to do - } else { - aai.removeAppender(appender); + Remove the appender passed as parameter form the list of appenders. + + @since 0.8.2 + */ + synchronized + public + void removeAppender(Appender appender) { + if(appender == null || aai == null) { + return; + } + boolean wasAttached = aai.isAttached(appender); + aai.removeAppender(appender); + if (wasAttached) { + fireRemoveAppenderEvent(appender); } - } finally { - lock.releaseWriteLock(); - } } /** - * Remove the appender with the name passed as parameter form the list of - * appenders. - * - *

Does not close the appender.

- * - * @since 0.8.2 - */ - public void removeAppender(String name) { - lock.getWriteLock(); - try { - if ((name == null) || (aai == null)) { - // nothing to do - } else { - aai.removeAppender(name); + Remove the appender with the name passed as parameter form the + list of appenders. + + @since 0.8.2 */ + synchronized + public + void removeAppender(String name) { + if(name == null || aai == null) { + return; + } + Appender appender = aai.getAppender(name); + aai.removeAppender(name); + if (appender != null) { + fireRemoveAppenderEvent(appender); } - } finally { - lock.releaseWriteLock(); - } } /** - * Set the additivity flag for this Category instance. - * - * @since 0.8.1 + Set the additivity flag for this Category instance. + @since 0.8.1 */ - public void setAdditivity(boolean additive) { + public + void setAdditivity(boolean additive) { this.additive = additive; } /** - * Only the Hiearchy class can set the hiearchy of a category. Default - * package access is MANDATORY here. - */ - final void setHierarchy(LoggerRepository repository) { + Only the Hiearchy class can set the hiearchy of a + category. Default package access is MANDATORY here. */ + final + void setHierarchy(LoggerRepository repository) { this.repository = repository; } /** - * Set the level of this Category. If you are passing any of - * Level.TRACE, Level.DEBUG, - * Level.INFO, Level.WARN, - * Level.ERROR, or Level.FATAL - * as a parameter, you need to case them as Level. - * - *

- * As in - *

    logger.setLevel((Level) Level.DEBUG); 
- *

- * - *

- * Null values are admitted. - *

- */ - public void setLevel(Level level) { + Set the level of this Category. If you are passing any of + Level.DEBUG, Level.INFO, + Level.WARN, Level.ERROR, + Level.FATAL as a parameter, you need to case them as + Level. + +

As in

    logger.setLevel((Level) Level.DEBUG); 
+ + +

Null values are admitted. */ + public + void setLevel(Level level) { this.level = level; } + /** - * Set the level of this Category. - * - *

- * Null values are admitted. - *

- * - * @deprecated Please use {@link #setLevel} instead. - */ - public void setPriority(Priority priority) { + Set the level of this Category. + +

Null values are admitted. + + @deprecated Please use {@link #setLevel} instead. + */ + public + void setPriority(Priority priority) { this.level = (Level) priority; } + /** - * Set the resource bundle to be used with localized logging methods {@link - * #l7dlog(Priority,String,Throwable)} and {@link - * #l7dlog(Priority,String,Object[],Throwable)}. - * - * @since 0.8.4 + Set the resource bundle to be used with localized logging + methods {@link #l7dlog(Priority,String,Throwable)} and {@link + #l7dlog(Priority,String,Object[],Throwable)}. + + @since 0.8.4 */ - public void setResourceBundle(ResourceBundle bundle) { + public + void setResourceBundle(ResourceBundle bundle) { resourceBundle = bundle; } /** - * Calling this method will safely close and remove all appenders - * in all the categories including root contained in the default hierachy. - * - *

- * Some appenders such as {@link org.apache.log4j.net.SocketAppender} and - * {@link AsyncAppender} need to be closed before the application exists. - * Otherwise, pending logging events might be lost. - *

- * - *

- * The shutdown method is careful to close nested appenders - * before closing regular appenders. This is allows configurations where a - * regular appender is attached to a category and again to a nested - * appender. - *

- * - * @since 1.0 - * @deprecated Please use {@link LogManager#shutdown()} instead. - */ - public static void shutdown() { + Calling this method will safely close and remove all + appenders in all the categories including root contained in the + default hierachy. + +

Some appenders such as {@link org.apache.log4j.net.SocketAppender} + and {@link AsyncAppender} need to be closed before the + application exists. Otherwise, pending logging events might be + lost. + +

The shutdown method is careful to close nested + appenders before closing regular appenders. This is allows + configurations where a regular appender is attached to a category + and again to a nested appender. + + @deprecated Please use {@link LogManager#shutdown()} instead. + + @since 1.0 + */ + public + static + void shutdown() { LogManager.shutdown(); } - + /** - * Check whether this category is enabled for the WARN Level. See also - * {@link #isDebugEnabled()}. - * - * @return boolean - true if this category is enabled for level - * WARN, false otherwise. - */ - public boolean isWarnEnabled() { - if (repository.isDisabled(Level.WARN_INT)) { - return false; - } + Log a message object with the {@link Level#WARN WARN} Level. - return Level.WARN.isGreaterOrEqual(this.getEffectiveLevel()); - } +

This method first checks if this category is WARN + enabled by comparing the level of this category with {@link + Level#WARN WARN} Level. If the category is WARN + enabled, then it converts the message object passed as parameter + to a string by invoking the appropriate + {@link org.apache.log4j.or.ObjectRenderer}. It + proceeds to call all the registered appenders in this category and + also higher in the hieararchy depending on the value of the + additivity flag. - - /** - * Log a message object with the {@link Level#WARN WARN} Level. - * - *

- * This method first checks if this category is WARN enabled by - * comparing the level of this category with {@link Level#WARN WARN} Level. - * If the category is WARN enabled, then it converts the - * message object passed as parameter to a string by invoking the - * appropriate {@link org.apache.log4j.or.ObjectRenderer}. It proceeds to - * call all the registered appenders in this category and also higher in - * the hieararchy depending on the value of the additivity flag. - *

- * - *

- * WARNING Note that passing a {@link Throwable} to this method will - * print the name of the Throwable but no stack trace. To print a stack - * trace use the {@link #warn(Object, Throwable)} form instead. - *

- * - *

- * - * @param message the message object to log. - */ - public void warn(Object message) { - if (repository.isDisabled(Level.WARN_INT)) { - return; +

WARNING Note that passing a {@link Throwable} to this + method will print the name of the Throwable but no stack trace. To + print a stack trace use the {@link #warn(Object, Throwable)} form + instead.

+ + @param message the message object to log. */ + public + void warn(Object message) { + if(repository.isDisabled( Level.WARN_INT)) { + return; } - if (Level.WARN.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, Level.WARN, message, null); + if(Level.WARN.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, Level.WARN, message, null); } } /** - * Log a message with the WARN level including the stack trace - * of the {@link Throwable}t passed as parameter. - * - *

- * See {@link #warn(Object)} for more detailed information. - *

- * - * @param message the message object to log. - * @param t the exception to log, including its stack trace. - */ - public void warn(Object message, Throwable t) { - if (repository.isDisabled(Level.WARN_INT)) { - return; - } + Log a message with the WARN level including the + stack trace of the {@link Throwable} t passed as + parameter. - if (Level.WARN.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, Level.WARN, message, t); - } - } - - /** - * Log a message with the WARN level with message formatting - * done according to the value of messagePattern and - * arg parameters. - *

- * 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 messagePattern. - * @since 1.3 - */ - public void warn(Object messagePattern, Object arg) { - if (repository.isDisabled(Level.WARN_INT)) { - return; - } +

See {@link #warn(Object)} for more detailed information. - 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 WARN level with message formatting - * done according to the messagePattern and the arguments arg1 and arg2. - *

- * 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.3 - */ - public void warn(String messagePattern, Object arg1, Object arg2) { - if (repository.isDisabled(Level.WARN_INT)) { - return; + @param message the message object to log. + @param t the exception to log, including its stack trace. */ + public + void warn(Object message, Throwable t) { + 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); + if(Level.WARN.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, Level.WARN, message, t); } } } -// End of class: Category.java diff --git a/src/main/java/org/apache/log4j/CategoryKey.java b/src/main/java/org/apache/log4j/CategoryKey.java index 36f846a49a..e6f96c63f5 100644 --- a/src/main/java/org/apache/log4j/CategoryKey.java +++ b/src/main/java/org/apache/log4j/CategoryKey.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,13 +17,14 @@ package org.apache.log4j; - /** - CategoryKey is heavily used internally to accelerate hash table searches. - @author Ceki Gülcü + CategoryKey is a wrapper for String that apparently accellerated + hash table lookup in early JVM's. + @author Ceki Gülcü */ class CategoryKey { - String name; + + String name; int hashCache; CategoryKey(String name) { @@ -30,19 +32,23 @@ class CategoryKey { hashCache = name.hashCode(); } - public final int hashCode() { + final + public + int hashCode() { return hashCache; } - public final boolean equals(Object rArg) { - if (this == rArg) { - return true; + final + public + boolean equals(Object rArg) { + if(this == rArg) { + return true; } - - if ((rArg != null) && (CategoryKey.class == rArg.getClass())) { - return name.equals(((CategoryKey) rArg).name); + + if(rArg != null && CategoryKey.class == rArg.getClass()) { + return name.equals(((CategoryKey)rArg ).name); } else { - return false; + return false; } } } diff --git a/src/main/java/org/apache/log4j/ConsoleAppender.java b/src/main/java/org/apache/log4j/ConsoleAppender.java index 9332bb34a4..b44fd5fddc 100644 --- a/src/main/java/org/apache/log4j/ConsoleAppender.java +++ b/src/main/java/org/apache/log4j/ConsoleAppender.java @@ -1,126 +1,133 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ + package org.apache.log4j; import java.io.IOException; import java.io.OutputStream; - +import org.apache.log4j.helpers.LogLog; /** * ConsoleAppender appends log events to System.out or * System.err using a layout specified by the user. The * default target is System.out. * - * @author Ceki Gülcü + * @author Ceki Gülcü * @author Curt Arnold * @since 1.1 */ public class ConsoleAppender extends WriterAppender { - public static final String SYSTEM_OUT = "System.out"; - public static final String SYSTEM_ERR = "System.err"; - protected String target = SYSTEM_OUT; - /** - * Determines if the appender honors reassignments of System.out - * or System.err made after configuration. - */ - private boolean follow = false; + public static final String SYSTEM_OUT = "System.out"; + public static final String SYSTEM_ERR = "System.err"; + protected String target = SYSTEM_OUT; - /** - * Constructs an unconfigured appender. - */ - public ConsoleAppender() { - } + /** + * Determines if the appender honors reassignments of System.out + * or System.err made after configuration. + */ + private boolean follow = false; + + /** + * Constructs an unconfigured appender. + */ + public ConsoleAppender() { + } /** * Creates a configured appender. * * @param layout layout, may not be null. */ - public ConsoleAppender(final Layout layout) { - setLayout(layout); - activateOptions(); - } + public ConsoleAppender(Layout layout) { + this(layout, SYSTEM_OUT); + } /** * Creates a configured appender. * @param layout layout, may not be null. - * @param targetStr target, either "System.err" or "System.out". + * @param target target, either "System.err" or "System.out". */ - public ConsoleAppender(final Layout layout, final String targetStr) { - setLayout(layout); - setTarget(targetStr); - activateOptions(); - } - - /** - * Sets the value of the Target option. Recognized values - * are "System.out" and "System.err". Any other value will be - * ignored. - * */ - public void setTarget(final String value) { - String v = value.trim(); - - if (SYSTEM_OUT.equalsIgnoreCase(v)) { - target = SYSTEM_OUT; - } else if (SYSTEM_ERR.equalsIgnoreCase(v)) { - target = SYSTEM_ERR; - } else { - getLogger().warn("[{}] should be System.out or System.err.", value); - getLogger().warn("Using previously set target, System.out by default."); - } - } + public ConsoleAppender(Layout layout, String target) { + setLayout(layout); + setTarget(target); + activateOptions(); + } - /** - * Returns the current value of the Target property. The - * default value of the option is "System.out". - * - * See also {@link #setTarget}. - * */ - public String getTarget() { - return target; + /** + * Sets the value of the Target option. Recognized values + * are "System.out" and "System.err". Any other value will be + * ignored. + * */ + public + void setTarget(String value) { + String v = value.trim(); + + if (SYSTEM_OUT.equalsIgnoreCase(v)) { + target = SYSTEM_OUT; + } else if (SYSTEM_ERR.equalsIgnoreCase(v)) { + target = SYSTEM_ERR; + } else { + targetWarn(value); } + } - /** - * Sets whether the appender honors reassignments of System.out - * or System.err made after configuration. - * @param newValue if true, appender will use value of System.out or - * System.err in force at the time when logging events are appended. - * @since 1.2.13 - */ - public final void setFollow(final boolean newValue) { - follow = newValue; - } + /** + * Returns the current value of the Target property. The + * default value of the option is "System.out". + * + * See also {@link #setTarget}. + * */ + public + String getTarget() { + return target; + } - /** - * Gets whether the appender honors reassignments of System.out - * or System.err made after configuration. - * @return true if appender will use value of System.out or - * System.err in force at the time when logging events are appended. - * @since 1.2.13 - */ - public final boolean getFollow() { - return follow; - } + /** + * Sets whether the appender honors reassignments of System.out + * or System.err made after configuration. + * @param newValue if true, appender will use value of System.out or + * System.err in force at the time when logging events are appended. + * @since 1.2.13 + */ + public final void setFollow(final boolean newValue) { + follow = newValue; + } + + /** + * Gets whether the appender honors reassignments of System.out + * or System.err made after configuration. + * @return true if appender will use value of System.out or + * System.err in force at the time when logging events are appended. + * @since 1.2.13 + */ + public final boolean getFollow() { + return follow; + } + void targetWarn(String val) { + LogLog.warn("["+val+"] should be System.out or System.err."); + LogLog.warn("Using previously set target, System.out by default."); + } - /** - * Prepares the appender for use. - */ - public void activateOptions() { + /** + * Prepares the appender for use. + */ + public void activateOptions() { if (follow) { if (target.equals(SYSTEM_ERR)) { setWriter(createWriter(new SystemErrStream())); @@ -136,8 +143,8 @@ public void activateOptions() { } super.activateOptions(); - } - + } + /** * {@inheritDoc} */ @@ -148,7 +155,7 @@ void closeWriter() { super.closeWriter(); } } - + /** * An implementation of OutputStream that redirects to the @@ -209,4 +216,5 @@ public void write(final int b) throws IOException { System.out.write(b); } } + } diff --git a/src/main/java/org/apache/log4j/DailyRollingFileAppender.java b/src/main/java/org/apache/log4j/DailyRollingFileAppender.java index 22052ac6a9..79a3b5c6b6 100644 --- a/src/main/java/org/apache/log4j/DailyRollingFileAppender.java +++ b/src/main/java/org/apache/log4j/DailyRollingFileAppender.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -20,6 +21,7 @@ import java.io.IOException; import java.io.File; +import java.io.InterruptedIOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.GregorianCalendar; @@ -33,6 +35,12 @@ /** DailyRollingFileAppender extends {@link FileAppender} so that the underlying file is rolled over at a user chosen frequency. + + DailyRollingFileAppender has been observed to exhibit + synchronization issues and data loss. The log4j extras + companion includes alternatives which should be considered + for new deployments and which are discussed in the documentation + for org.apache.log4j.rolling.RollingFileAppender.

The rolling schedule is specified by the DatePattern option. This pattern should follow the {@link SimpleDateFormat} @@ -130,9 +138,7 @@ @author Eirik Lygre - @author Ceki Gülcü - @deprecated Since log4j 1.3, use org.apache.log4j.rolling.RollingFileAppender instead. - */ + @author Ceki Gülcü*/ public class DailyRollingFileAppender extends FileAppender { @@ -173,7 +179,9 @@ public class DailyRollingFileAppender extends FileAppender { SimpleDateFormat sdf; - private final RollingCalendar rc = new RollingCalendar(); + RollingCalendar rc = new RollingCalendar(); + + int checkPeriod = TOP_OF_TROUBLE; // The gmtTimeZone is used only in computeCheckPeriod() method. static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT"); @@ -269,7 +277,7 @@ void printPeriodicity(int type) { // GMT (the epoch). int computeCheckPeriod() { - RollingCalendar rollingCalendar = new RollingCalendar(gmtTimeZone, Locale.ENGLISH); + RollingCalendar rollingCalendar = new RollingCalendar(gmtTimeZone, Locale.getDefault()); // set sate to 1970-01-01 00:00:00 GMT Date epoch = new Date(0); if(datePattern != null) { @@ -327,10 +335,10 @@ void rollOver() throws IOException { try { // This will also close the file. This is OK since multiple // close operations are safe. - this.setFile(fileName, false, this.bufferedIO, this.bufferSize); + this.setFile(fileName, true, this.bufferedIO, this.bufferSize); } catch(IOException e) { - errorHandler.error("setFile("+fileName+", false) call failed."); + errorHandler.error("setFile("+fileName+", true) call failed."); } scheduledFilename = datedFilename; } @@ -352,7 +360,10 @@ protected void subAppend(LoggingEvent event) { rollOver(); } catch(IOException ioe) { - LogLog.error("rollOver() failed.", ioe); + if (ioe instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.error("rollOver() failed.", ioe); } } super.subAppend(event); @@ -362,12 +373,12 @@ protected void subAppend(LoggingEvent event) { /** * RollingCalendar is a helper class to DailyRollingFileAppender. * Given a periodicity type and the current time, it computes the - * start of the next interval. - * @deprecated Since log4j 1.3. + * start of the next interval. * */ class RollingCalendar extends GregorianCalendar { + private static final long serialVersionUID = -3560331770601814177L; - private int type = DailyRollingFileAppender.TOP_OF_TROUBLE; + int type = DailyRollingFileAppender.TOP_OF_TROUBLE; RollingCalendar() { super(); diff --git a/src/main/java/org/apache/log4j/DefaultCategoryFactory.java b/src/main/java/org/apache/log4j/DefaultCategoryFactory.java new file mode 100644 index 0000000000..c7bb0c4668 --- /dev/null +++ b/src/main/java/org/apache/log4j/DefaultCategoryFactory.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j; + +import org.apache.log4j.spi.LoggerFactory; + +class DefaultCategoryFactory implements LoggerFactory { + + DefaultCategoryFactory() { + } + + public + Logger makeNewLoggerInstance(String name) { + return new Logger(name); + } +} diff --git a/src/main/java/org/apache/log4j/DefaultLoggerFactory.java b/src/main/java/org/apache/log4j/DefaultLoggerFactory.java deleted file mode 100644 index 7954da394d..0000000000 --- a/src/main/java/org/apache/log4j/DefaultLoggerFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j; - -import org.apache.log4j.spi.LoggerFactory; - -/** - * Factory class that returns new {@link Logger} instances. - */ -public final class DefaultLoggerFactory implements LoggerFactory { - - public DefaultLoggerFactory() {} - - /** - * Returns a new {@link Logger} instance. - */ - public Logger makeNewLoggerInstance(String name) { - return new Logger(name); - } -} diff --git a/src/main/java/org/apache/log4j/DefaultThrowableRenderer.java b/src/main/java/org/apache/log4j/DefaultThrowableRenderer.java new file mode 100644 index 0000000000..29bfe061b5 --- /dev/null +++ b/src/main/java/org/apache/log4j/DefaultThrowableRenderer.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j; + +import org.apache.log4j.spi.ThrowableRenderer; + +import java.io.StringWriter; +import java.io.PrintWriter; +import java.io.LineNumberReader; +import java.io.StringReader; +import java.io.IOException; +import java.io.InterruptedIOException; +import java.util.ArrayList; + +/** + * Default implementation of ThrowableRenderer using + * Throwable.printStackTrace. + * + * @since 1.2.16 + */ +public final class DefaultThrowableRenderer implements ThrowableRenderer { + /** + * Construct new instance. + */ + public DefaultThrowableRenderer() { + + } + + + /** + * {@inheritDoc} + */ + public String[] doRender(final Throwable throwable) { + return render(throwable); + } + + /** + * Render throwable using Throwable.printStackTrace. + * @param throwable throwable, may not be null. + * @return string representation. + */ + public static String[] render(final Throwable throwable) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + try { + throwable.printStackTrace(pw); + } catch(RuntimeException ex) { + } + pw.flush(); + LineNumberReader reader = new LineNumberReader( + new StringReader(sw.toString())); + ArrayList lines = new ArrayList(); + try { + String line = reader.readLine(); + while(line != null) { + lines.add(line); + line = reader.readLine(); + } + } catch(IOException ex) { + if (ex instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + lines.add(ex.toString()); + } + String[] tempRep = new String[lines.size()]; + lines.toArray(tempRep); + return tempRep; + } +} diff --git a/src/main/java/org/apache/log4j/Dispatcher.java b/src/main/java/org/apache/log4j/Dispatcher.java index 2ba2164d68..e879ff0abf 100644 --- a/src/main/java/org/apache/log4j/Dispatcher.java +++ b/src/main/java/org/apache/log4j/Dispatcher.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * diff --git a/src/main/java/org/apache/log4j/EnhancedPatternLayout.java b/src/main/java/org/apache/log4j/EnhancedPatternLayout.java new file mode 100644 index 0000000000..a8158dad85 --- /dev/null +++ b/src/main/java/org/apache/log4j/EnhancedPatternLayout.java @@ -0,0 +1,571 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j; + +import org.apache.log4j.helpers.OptionConverter; +import org.apache.log4j.helpers.PatternConverter; +import org.apache.log4j.pattern.BridgePatternConverter; +import org.apache.log4j.spi.LoggingEvent; + + +// Contributors: Nelson Minar +// Anders Kristensen + +/** + * This class is an enhanced version of org.apache.log4j.PatternLayout + * which was originally developed as part of the abandoned log4j 1.3 + * effort and has been available in the extras companion. + * This pattern layout should be used in preference to + * org.apache.log4j.PatternLayout except when compatibility + * where PatternLayout has been extended either through subclassing + * or alternative pattern parsers. + * + * + *

A flexible layout configurable with pattern string. The goal of this class + * is to {@link #format format} a {@link LoggingEvent} and return the results + * in a {@link StringBuffer}. The format of the result depends on the + * conversion pattern. + *

+ * + *

The conversion pattern is closely related to the conversion + * pattern of the printf function in C. A conversion pattern is + * composed of literal text and format control expressions called + * conversion specifiers. + * + *

Note that you are free to insert any literal text within the + * conversion pattern. + *

+ +

Each conversion specifier starts with a percent sign (%) and is + followed by optional format modifiers and a conversion + character. The conversion character specifies the type of + data, e.g. category, priority, date, thread name. The format + modifiers control such things as field width, padding, left and + right justification. The following is a simple example. + +

Let the conversion pattern be "%-5p [%t]: %m%n" and assume + that the log4j environment was set to use a EnhancedPatternLayout. Then the + statements +

+   Category root = Category.getRoot();
+   root.debug("Message 1");
+   root.warn("Message 2");
+   
+ would yield the output +
+   DEBUG [main]: Message 1
+   WARN  [main]: Message 2
+   
+ +

Note that there is no explicit separator between text and + conversion specifiers. The pattern parser knows when it has reached + the end of a conversion specifier when it reads a conversion + character. In the example above the conversion specifier + %-5p means the priority of the logging event should be left + justified to a width of five characters. + + The recognized conversion characters are + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Conversion CharacterEffect
cUsed to output the category of the logging event. The + category conversion specifier can be optionally followed by + NameAbbreviator pattern. + +

For example, for the category name "alpha.beta.gamma" the pattern + %c{2} will output the last two elements ("beta.gamma"), + %c{-2} will remove two elements leaving "gamma", + %c{1.} will output "a.b.gamma". + +

CUsed to output the fully qualified class name of the caller + issuing the logging request. This conversion specifier + can be optionally followed by precision specifier, that + is a decimal constant in brackets. + + Used to output the category of the logging event. The + category conversion specifier can be optionally followed by + NameAbbreviator pattern. + +

For example, for the category name "alpha.beta.gamma" the pattern + %c{2} will output the last two elements ("beta.gamma"), + %c{-2} will remove two elements leaving "gamma", + %c{1.} will output "a.b.gamma". + +

WARNING Generating the caller class information is + slow. Thus, its use should be avoided unless execution speed is + not an issue. + +

d Used to output the date of + the logging event. The date conversion specifier may be + followed by a set of braces containing a + date and time pattern strings {@link java.text.SimpleDateFormat}, + ABSOLUTE, DATE or ISO8601 + and a set of braces containing a time zone id per + {@link java.util.TimeZone#getTimeZone(String)}. + For example, %d{HH:mm:ss,SSS}, + %d{dd MMM yyyy HH:mm:ss,SSS}, + %d{DATE} or %d{HH:mm:ss}{GMT+0}. If no date format specifier is given then + ISO8601 format is assumed. +
FUsed to output the file name where the logging request was + issued. + +

WARNING Generating caller location information is + extremely slow and should be avoided unless execution speed + is not an issue. + +

lUsed to output location information of the caller which generated + the logging event. + +

The location information depends on the JVM implementation but + usually consists of the fully qualified name of the calling + method followed by the callers source the file name and line + number between parentheses. + +

The location information can be very useful. However, its + generation is extremely slow and should be avoided + unless execution speed is not an issue. + +

LUsed to output the line number from where the logging request + was issued. + +

WARNING Generating caller location information is + extremely slow and should be avoided unless execution speed + is not an issue. + +

mUsed to output the application supplied message associated with + the logging event.
MUsed to output the method name where the logging request was + issued. + +

WARNING Generating caller location information is + extremely slow and should be avoided unless execution speed + is not an issue. + +

nOutputs the platform dependent line separator character or + characters. + +

This conversion character offers practically the same + performance as using non-portable line separator strings such as + "\n", or "\r\n". Thus, it is the preferred way of specifying a + line separator. + + +

pUsed to output the priority of the logging event.
rUsed to output the number of milliseconds elapsed since the construction + of the layout until the creation of the logging event.
tUsed to output the name of the thread that generated the + logging event.
xUsed to output the NDC (nested diagnostic context) associated + with the thread that generated the logging event. +
X + +

Used to output the MDC (mapped diagnostic context) associated + with the thread that generated the logging event. The X + conversion character can be followed by the key for the + map placed between braces, as in %X{clientNumber} where + clientNumber is the key. The value in the MDC + corresponding to the key will be output. If no additional sub-option + is specified, then the entire contents of the MDC key value pair set + is output using a format {{key1,val1},{key2,val2}}

+ +

See {@link MDC} class for more details. +

+ +
properties +

Used to output the Properties associated + with the logging event. The properties + conversion word can be followed by the key for the + map placed between braces, as in %properties{application} where + application is the key. The value in the Properties bundle + corresponding to the key will be output. If no additional sub-option + is specified, then the entire contents of the Properties key value pair set + is output using a format {{key1,val1},{key2,val2}}

+
throwable +

Used to output the Throwable trace that has been bound to the LoggingEvent, by + default this will output the full trace as one would normally + find by a call to Throwable.printStackTrace(). + %throwable{short} or %throwable{1} will output the first line of + stack trace. throwable{none} or throwable{0} will suppress + the stack trace. %throwable{n} will output n lines of stack trace + if a positive integer or omit the last -n lines if a negative integer. + If no %throwable pattern is specified, the appender will take + responsibility to output the stack trace as it sees fit.

+
%The sequence %% outputs a single percent sign. +
+ +

By default the relevant information is output as is. However, + with the aid of format modifiers it is possible to change the + minimum field width, the maximum field width, justification + and truncation. + +

The optional format modifier are placed between the percent sign + and the conversion character. + +

The left justification flag, the minus sign (-), + the right truncation flag, the exclamation mark (!), + or any combination appear first. Followed by the + optional minimum field width modifier. This is a decimal + constant that represents the minimum number of characters to + output. If the data item requires fewer characters, it is padded on + either the left or the right until the minimum width is + reached. The default is to pad on the left (right justify) but you + can specify right padding with the left justification flag. The + padding character is space. If the data item is larger than the + minimum field width, the field is expanded to accommodate the + data. The value is never truncated. + +

This behavior can be changed using the maximum field + width modifier which is designated by a period followed by a + decimal constant. If the data item is longer than the maximum + field, then the extra characters are removed from the + beginning of the data item and not from the end. For + example, it the maximum field width is eight and the data item is + ten characters long, then the first two characters of the data item + are dropped. This behavior deviates from the printf function in C + where truncation is done from the end. The right truncation flag, + described previously, will override this behavior. + +

Below are various format modifier examples for the category + conversion specifier. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Format modifier + left justify + minimum width + maximum width + comment + +
%20cfalse20noneLeft pad with spaces if the category name is less than 20 + characters long. + +
%-20c true 20 none Right pad with + spaces if the category name is less than 20 characters long. + +
%.30cNAnone30Truncate from the beginning if the category name is longer than 30 + characters. + +
%!.30cNAnone30Truncate from the end if the category name is longer than 30 + characters. + +
%20.30cfalse2030Left pad with spaces if the category name is shorter than 20 + characters. However, if category name is longer than 30 characters, + then truncate from the beginning. + +
%-20.30ctrue2030Right pad with spaces if the category name is shorter than 20 + characters. However, if category name is longer than 30 characters, + then truncate from the beginning. + +
+ +

Below are some examples of conversion patterns. + +

+ +

%r [%t] %-5p %c %x - %m%n +

This is essentially the TTCC layout. + +

%-6r [%15.15t] %-5p %30.30c %x - %m%n + +

Similar to the TTCC layout except that the relative time is + right padded if less than 6 digits, thread name is right padded if + less than 15 characters and truncated if longer and the category + name is left padded if shorter than 30 characters and truncated if + longer. + +
+ +

The above text is largely inspired from Peter A. Darnell and + Philip E. Margolis' highly recommended book "C -- a Software + Engineering Approach", ISBN 0-387-97389-3. + + @author James P. Cakalic + @author Ceki Gülcü + + + @since 1.2.16 */ +public class EnhancedPatternLayout extends Layout { + /** Default pattern string for log output. Currently set to the + string "%m%n" which just prints the application supplied + message. */ + public static final String DEFAULT_CONVERSION_PATTERN = "%m%n"; + + /** A conversion pattern equivalent to the TTCCCLayout. + Current value is %r [%t] %p %c %x - %m%n. */ + public static final String TTCC_CONVERSION_PATTERN = + "%r [%t] %p %c %x - %m%n"; + + /** + * Initial size of internal buffer, no longer used. + * @deprecated since 1.3 + */ + protected final int BUF_SIZE = 256; + + /** + * Maximum capacity of internal buffer, no longer used. + * @deprecated since 1.3 + */ + protected final int MAX_CAPACITY = 1024; + + /** + * Customized pattern conversion rules are stored under this key in the + * {@link org.apache.log4j.spi.LoggerRepository LoggerRepository} object store. + */ + public static final String PATTERN_RULE_REGISTRY = "PATTERN_RULE_REGISTRY"; + + + /** + * Initial converter for pattern. + */ + private PatternConverter head; + + /** + * Conversion pattern. + */ + private String conversionPattern; + + /** + * True if any element in pattern formats information from exceptions. + */ + private boolean handlesExceptions; + + /** + Constructs a EnhancedPatternLayout using the DEFAULT_LAYOUT_PATTERN. + + The default pattern just produces the application supplied message. + */ + public EnhancedPatternLayout() { + this(DEFAULT_CONVERSION_PATTERN); + } + + /** + * Constructs a EnhancedPatternLayout using the supplied conversion pattern. + * @param pattern conversion pattern. + */ + public EnhancedPatternLayout(final String pattern) { + this.conversionPattern = pattern; + head = createPatternParser( + (pattern == null) ? DEFAULT_CONVERSION_PATTERN : pattern).parse(); + if (head instanceof BridgePatternConverter) { + handlesExceptions = !((BridgePatternConverter) head).ignoresThrowable(); + } else { + handlesExceptions = false; + } + } + + /** + * Set the ConversionPattern option. This is the string which + * controls formatting and consists of a mix of literal content and + * conversion specifiers. + * + * @param conversionPattern conversion pattern. + */ + public void setConversionPattern(final String conversionPattern) { + this.conversionPattern = + OptionConverter.convertSpecialChars(conversionPattern); + head = createPatternParser(this.conversionPattern).parse(); + if (head instanceof BridgePatternConverter) { + handlesExceptions = !((BridgePatternConverter) head).ignoresThrowable(); + } else { + handlesExceptions = false; + } + } + + /** + * Returns the value of the ConversionPattern option. + * @return conversion pattern. + */ + public String getConversionPattern() { + return conversionPattern; + } + + + /** + Returns PatternParser used to parse the conversion string. Subclasses + may override this to return a subclass of PatternParser which recognize + custom conversion characters. + + @since 0.9.0 + */ + protected org.apache.log4j.helpers.PatternParser createPatternParser(String pattern) { + return new org.apache.log4j.pattern.BridgePatternParser(pattern); + } + + + /** + Activates the conversion pattern. Do not forget to call this method after + you change the parameters of the EnhancedPatternLayout instance. + */ + public void activateOptions() { + // nothing to do. + } + + + /** + * Formats a logging event to a writer. + * @param event logging event to be formatted. + */ + public String format(final LoggingEvent event) { + StringBuffer buf = new StringBuffer(); + for(PatternConverter c = head; + c != null; + c = c.next) { + c.format(buf, event); + } + return buf.toString(); + } + + /** + * Will return false if any of the conversion specifiers in the pattern + * handles {@link Exception Exceptions}. + * @return true if the pattern formats any information from exceptions. + */ + public boolean ignoresThrowable() { + return !handlesExceptions; + } +} diff --git a/src/main/java/org/apache/log4j/EnhancedThrowableRenderer.java b/src/main/java/org/apache/log4j/EnhancedThrowableRenderer.java new file mode 100644 index 0000000000..c5b8d7b00a --- /dev/null +++ b/src/main/java/org/apache/log4j/EnhancedThrowableRenderer.java @@ -0,0 +1,168 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j; + +import org.apache.log4j.spi.ThrowableRenderer; + +import java.io.File; +import java.lang.reflect.Method; +import java.net.URL; +import java.security.CodeSource; +import java.util.HashMap; +import java.util.Map; + +/** + * Enhanced implementation of ThrowableRenderer. Uses Throwable.getStackTrace + * if running on JDK 1.4 or later and delegates to DefaultThrowableRenderer.render + * on earlier virtual machines. + * + * @since 1.2.16 + */ +public final class EnhancedThrowableRenderer implements ThrowableRenderer { + /** + * Throwable.getStackTrace() method. + */ + private Method getStackTraceMethod; + /** + * StackTraceElement.getClassName() method. + */ + private Method getClassNameMethod; + + + /** + * Construct new instance. + */ + public EnhancedThrowableRenderer() { + try { + Class[] noArgs = null; + getStackTraceMethod = Throwable.class.getMethod("getStackTrace", noArgs); + Class ste = Class.forName("java.lang.StackTraceElement"); + getClassNameMethod = ste.getMethod("getClassName", noArgs); + } catch(Exception ex) { + } + } + + /** + * {@inheritDoc} + */ + public String[] doRender(final Throwable throwable) { + if (getStackTraceMethod != null) { + try { + Object[] noArgs = null; + Object[] elements = (Object[]) getStackTraceMethod.invoke(throwable, noArgs); + String[] lines = new String[elements.length + 1]; + lines[0] = throwable.toString(); + Map classMap = new HashMap(); + for(int i = 0; i < elements.length; i++) { + lines[i+1] = formatElement(elements[i], classMap); + } + return lines; + } catch(Exception ex) { + } + } + return DefaultThrowableRenderer.render(throwable); + } + + /** + * Format one element from stack trace. + * @param element element, may not be null. + * @param classMap map of class name to location. + * @return string representation of element. + */ + private String formatElement(final Object element, final Map classMap) { + StringBuffer buf = new StringBuffer("\tat "); + buf.append(element); + try { + String className = getClassNameMethod.invoke(element, (Object[]) null).toString(); + Object classDetails = classMap.get(className); + if (classDetails != null) { + buf.append(classDetails); + } else { + Class cls = findClass(className); + int detailStart = buf.length(); + buf.append('['); + try { + CodeSource source = cls.getProtectionDomain().getCodeSource(); + if (source != null) { + URL locationURL = source.getLocation(); + if (locationURL != null) { + // + // if a file: URL + // + if ("file".equals(locationURL.getProtocol())) { + String path = locationURL.getPath(); + if (path != null) { + // + // find the last file separator character + // + int lastSlash = path.lastIndexOf('/'); + int lastBack = path.lastIndexOf(File.separatorChar); + if (lastBack > lastSlash) { + lastSlash = lastBack; + } + // + // if no separator or ends with separator (a directory) + // then output the URL, otherwise just the file name. + // + if (lastSlash <= 0 || lastSlash == path.length() - 1) { + buf.append(locationURL); + } else { + buf.append(path.substring(lastSlash + 1)); + } + } + } else { + buf.append(locationURL); + } + } + } + } catch(SecurityException ex) { + } + buf.append(':'); + Package pkg = cls.getPackage(); + if (pkg != null) { + String implVersion = pkg.getImplementationVersion(); + if (implVersion != null) { + buf.append(implVersion); + } + } + buf.append(']'); + classMap.put(className, buf.substring(detailStart)); + } + } catch(Exception ex) { + } + return buf.toString(); + } + + /** + * Find class given class name. + * @param className class name, may not be null. + * @return class, will not be null. + * @throws ClassNotFoundException thrown if class can not be found. + */ + private Class findClass(final String className) throws ClassNotFoundException { + try { + return Thread.currentThread().getContextClassLoader().loadClass(className); + } catch (ClassNotFoundException e) { + try { + return Class.forName(className); + } catch (ClassNotFoundException e1) { + return getClass().getClassLoader().loadClass(className); + } + } + } + +} diff --git a/src/main/java/org/apache/log4j/FileAppender.java b/src/main/java/org/apache/log4j/FileAppender.java index 34f47fc8c2..0728695f5b 100644 --- a/src/main/java/org/apache/log4j/FileAppender.java +++ b/src/main/java/org/apache/log4j/FileAppender.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,15 +17,17 @@ package org.apache.log4j; -import org.apache.log4j.helpers.OptionConverter; - import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InterruptedIOException; import java.io.Writer; +import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.helpers.QuietWriter; +import org.apache.log4j.spi.ErrorCode; // Contibutors: Jens Uwe Pipka // Ben Sandee @@ -36,22 +39,18 @@ * has been deprecated and then removed. See the replacement * solutions: {@link WriterAppender} and {@link ConsoleAppender}. * - * @author Ceki Gülcü + * @author Ceki Gülcü * */ public class FileAppender extends WriterAppender { - /** - * The default size of the IO buffer. + /** Controls file truncatation. The default value for this variable + * is true, meaning that by default a + * FileAppender will append to an existing file and not + * truncate it. + * + *

This option is meaningful only if the FileAppender opens the + * file. */ - private static final int DEFAULT_BUFFER_SIZE = 8 * 1024; - /** - * Controls whether to append to or truncate an existing file. - * The default value for this variable is - * true, meaning that by default a FileAppender will - * append to an existing file and not truncate it. - * - *

This option is meaningful only if the FileAppender opens the file. - */ protected boolean fileAppend = true; /** @@ -63,13 +62,16 @@ public class FileAppender extends WriterAppender { protected boolean bufferedIO = false; /** - The size of the IO buffer. Default is 8K. */ - protected int bufferSize = DEFAULT_BUFFER_SIZE; + * Determines the size of IO buffer be. Default is 8K. + */ + protected int bufferSize = 8*1024; + /** The default constructor does not do anything. */ - public FileAppender() { + public + FileAppender() { } /** @@ -85,12 +87,11 @@ public FileAppender() { then buffered IO will be used to write to the output file. */ - public FileAppender( - Layout layout, String filename, boolean append, boolean bufferedIO, - int bufferSize) throws IOException { + public + FileAppender(Layout layout, String filename, boolean append, boolean bufferedIO, + int bufferSize) throws IOException { this.layout = layout; this.setFile(filename, append, bufferedIO, bufferSize); - activateOptions(); } /** @@ -102,11 +103,11 @@ public FileAppender( appended to. Otherwise, the file designated by filename will be truncated before being opened. */ - public FileAppender(Layout layout, String filename, boolean append) - throws IOException { + public + FileAppender(Layout layout, String filename, boolean append) + throws IOException { this.layout = layout; this.setFile(filename, append, false, bufferSize); - activateOptions(); } /** @@ -115,9 +116,9 @@ public FileAppender(Layout layout, String filename, boolean append) destination for this appender.

The file will be appended to. */ - public FileAppender(Layout layout, String filename) throws IOException { + public + FileAppender(Layout layout, String filename) throws IOException { this(layout, filename, true); - activateOptions(); } /** @@ -133,18 +134,21 @@ public void setFile(String file) { // Trim spaces from both ends. The users probably does not want // trailing spaces in file names. String val = file.trim(); - fileName = OptionConverter.stripDuplicateBackslashes(val); + fileName = val; } /** Returns the value of the Append option. */ - public boolean getAppend() { + public + boolean getAppend() { return fileAppend; } + /** Returns the value of the File option. */ - public String getFile() { + public + String getFile() { return fileName; } @@ -154,48 +158,66 @@ public String getFile() { Append properties. @since 0.8.1 */ - public void activateOptions() { - if (fileName != null) { + public + void activateOptions() { + if(fileName != null) { try { - setFile(fileName, fileAppend, bufferedIO, bufferSize); - super.activateOptions(); - } catch (java.io.IOException e) { - getLogger().error( - "setFile(" + fileName + "," + fileAppend + ") call failed.", e); + setFile(fileName, fileAppend, bufferedIO, bufferSize); + } + catch(java.io.IOException e) { + errorHandler.error("setFile("+fileName+","+fileAppend+") call failed.", + e, ErrorCode.FILE_OPEN_FAILURE); } } else { - getLogger().error("File option not set for appender [{}].", name); - getLogger().warn("Are you using FileAppender instead of ConsoleAppender?"); + //LogLog.error("File option not set for appender ["+name+"]."); + LogLog.warn("File option not set for appender ["+name+"]."); + LogLog.warn("Are you using FileAppender instead of ConsoleAppender?"); } } - /** - * Closes the previously opened file. - * - * @deprecated Use the super class' {@link #closeWriter} method instead. - */ - protected void closeFile() { - closeWriter(); + /** + Closes the previously opened file. + */ + protected + void closeFile() { + if(this.qw != null) { + try { + this.qw.close(); + } + catch(java.io.IOException e) { + if (e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + // Exceptionally, it does not make sense to delegate to an + // ErrorHandler. Since a closed appender is basically dead. + LogLog.error("Could not close " + qw, e); + } + } } /** Get the value of the BufferedIO option. -

BufferedIO will significantly increase performance on heavily +

BufferedIO will significatnly increase performance on heavily loaded systems. */ - public boolean getBufferedIO() { + public + boolean getBufferedIO() { return this.bufferedIO; } + /** Get the size of the IO buffer. */ - public int getBufferSize() { + public + int getBufferSize() { return this.bufferSize; } + + /** The Append option takes a boolean value. It is set to true by default. If true, then File @@ -206,7 +228,8 @@ public int getBufferSize() {

Note: Actual opening of the file is made when {@link #activateOptions} is called, not when the options are set. */ - public void setAppend(boolean flag) { + public + void setAppend(boolean flag) { fileAppend = flag; } @@ -216,22 +239,24 @@ public void setAppend(boolean flag) { will be opened and the resulting {@link java.io.Writer} wrapped around a {@link BufferedWriter}. - BufferedIO will significantly increase performance on heavily + BufferedIO will significatnly increase performance on heavily loaded systems. */ - public void setBufferedIO(boolean bufferedIO) { + public + void setBufferedIO(boolean bufferedIO) { this.bufferedIO = bufferedIO; - - if (bufferedIO) { + if(bufferedIO) { immediateFlush = false; } } + /** Set the size of the IO buffer. */ - public void setBufferSize(int bufferSize) { + public + void setBufferSize(int bufferSize) { this.bufferSize = bufferSize; } @@ -246,83 +271,78 @@ public void setBufferSize(int bufferSize) { or one of its subclasses, set its properties one by one and then call activateOptions. - @param filename The path to the log file. + @param fileName The path to the log file. @param append If true will append to fileName. Otherwise will - truncate fileName. - @param bufferedIO - @param bufferSize - - @throws IOException - - */ - public synchronized void setFile( - String filename, boolean append, boolean bufferedIO, int bufferSize) - throws IOException { - getLogger().debug("setFile called: {}, {}", fileName, append?"true":"false"); + truncate fileName. */ + public + synchronized + void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize) + throws IOException { + LogLog.debug("setFile called: "+fileName+", "+append); // It does not make sense to have immediate flush and bufferedIO. - if (bufferedIO) { + if(bufferedIO) { setImmediateFlush(false); } - closeWriter(); - + reset(); FileOutputStream ostream = null; try { - // - // attempt to create file - // - ostream = new FileOutputStream(filename, append); + // + // attempt to create file + // + ostream = new FileOutputStream(fileName, append); } catch(FileNotFoundException ex) { - // - // if parent directory does not exist then - // attempt to create it and try to create file - // see bug 9150 - // - File parentDir = new File(new File(filename).getParent()); - if(!parentDir.exists() && parentDir.mkdirs()) { - ostream = new FileOutputStream(filename, append); - } else { - throw ex; - } + // + // if parent directory does not exist then + // attempt to create it and try to create file + // see bug 9150 + // + String parentName = new File(fileName).getParent(); + if (parentName != null) { + File parentDir = new File(parentName); + if(!parentDir.exists() && parentDir.mkdirs()) { + ostream = new FileOutputStream(fileName, append); + } else { + throw ex; + } + } else { + throw ex; + } } Writer fw = createWriter(ostream); - - if (bufferedIO) { + if(bufferedIO) { fw = new BufferedWriter(fw, bufferSize); } - setQWForFiles(fw); - + this.setQWForFiles(fw); + this.fileName = fileName; this.fileAppend = append; this.bufferedIO = bufferedIO; - this.fileName = filename; this.bufferSize = bufferSize; writeHeader(); - getLogger().debug("setFile ended"); + LogLog.debug("setFile ended"); } - /** - Sets the quiet writer being used. - - This method is overriden by {@link RollingFileAppender}. - */ - protected - void setQWForFiles(final Writer writer) { - this.qw = createQuietWriter(writer); - } + /** + Sets the quiet writer being used. - /** - Close any previously opened file and call the parent's - reset. - @deprecated - */ - protected - void reset() { - closeFile(); - this.fileName = null; - super.reset(); - } + This method is overriden by {@link RollingFileAppender}. + */ + protected + void setQWForFiles(Writer writer) { + this.qw = new QuietWriter(writer, errorHandler); + } + /** + Close any previously opened file and call the parent's + reset. */ + protected + void reset() { + closeFile(); + this.fileName = null; + super.reset(); + } } + diff --git a/src/main/java/org/apache/log4j/HTMLLayout.java b/src/main/java/org/apache/log4j/HTMLLayout.java index 96a26561a9..164920829a 100644 --- a/src/main/java/org/apache/log4j/HTMLLayout.java +++ b/src/main/java/org/apache/log4j/HTMLLayout.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,444 +17,252 @@ package org.apache.log4j; -import org.apache.log4j.helpers.Transform; -import org.apache.log4j.pattern.FormattingInfo; -import org.apache.log4j.pattern.LiteralPatternConverter; -import org.apache.log4j.pattern.LoggingEventPatternConverter; -import org.apache.log4j.pattern.PatternConverter; -import org.apache.log4j.pattern.PatternParser; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggerRepositoryEx; import org.apache.log4j.spi.LoggingEvent; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - +import org.apache.log4j.spi.LocationInfo; +import org.apache.log4j.helpers.Transform; /** - * - * HTMLLayout outputs events in an HTML table. The content of the table columns - * are specified using a conversion pattern. See - * {@link org.apache.log4j.PatternLayout} for documentation on the available - * patterns. - * - * @author Ceki Gülcü - * @author Steve Mactaggart + * This layout outputs events in a HTML table. + * + * Appenders using this layout should have their encoding + * set to UTF-8 or UTF-16, otherwise events containing + * non ASCII characters could result in corrupted + * log files. + * + * @author Ceki Gülcü */ public class HTMLLayout extends Layout { - /** - * Default pattern string for log output. Currently set to the string - * "%m" which just prints the application supplied message. - */ - private static final String DEFAULT_CONVERSION_PATTERN = "%m"; - /** - * Customized pattern conversion rules are stored under this key in the - * {@link LoggerRepository} object store. - */ - private static final String PATTERN_RULE_REGISTRY = "PATTERN_RULE_REGISTRY"; + protected final int BUF_SIZE = 256; + protected final int MAX_CAPACITY = 1024; - /** - A string constant used in naming the option for setting the the - location information flag. Current value of this string - constant is LocationInfo. + static String TRACE_PREFIX = "
    "; -

Note that all option keys are case sensitive. + // output buffer appended to when format() is invoked + private StringBuffer sbuf = new StringBuffer(BUF_SIZE); - @deprecated Options are now handled using the JavaBeans paradigm. - This constant is not longer needed and will be removed in the - near term. + /** + A string constant used in naming the option for setting the the + location information flag. Current value of this string + constant is LocationInfo. - */ - public static final String LOCATION_INFO_OPTION = "LocationInfo"; +

Note that all option keys are case sensitive. - /** - A string constant used in naming the option for setting the the - HTML document title. Current value of this string - constant is Title. @deprecated Options are now handled using the JavaBeans paradigm. This constant is not longer needed and will be removed in the near term. - */ - public static final String TITLE_OPTION = "Title"; + */ + public static final String LOCATION_INFO_OPTION = "LocationInfo"; - private static final String TRACE_PREFIX = "
    "; - protected final int BUF_SIZE = 256; - protected final int MAX_CAPACITY = 1024; - private String pattern; - private LoggingEventPatternConverter[] patternConverters; - private FormattingInfo[] patternFields; - private String title = "Log4J Log Messages"; - private boolean locationInfo; - - private boolean internalCSS = false; - private String url2ExternalCSS = "http://logging.apache.org/log4j/docs/css/eventTable-1.0.css"; - - // Does our PatternConverter chain handle throwable on its own? - private boolean chainHandlesThrowable; - - - // counter keeping track of the rows output - private boolean odd = true; - /** - * Constructs a PatternLayout using the DEFAULT_LAYOUT_PATTERN. - * - * The default pattern just produces the application supplied message. - */ - public HTMLLayout() { - this(DEFAULT_CONVERSION_PATTERN); - } + A string constant used in naming the option for setting the the + HTML document title. Current value of this string + constant is Title. + */ + public static final String TITLE_OPTION = "Title"; - /** - * Constructs a PatternLayout using the supplied conversion pattern. - */ - public HTMLLayout(String pattern) { - this.pattern = pattern; - activateOptions(); - } - - /** - The LocationInfo option takes a boolean value. By - default, it is set to false which means there will be no location - information output by this layout. If the the option is set to - true, then the file name and line number of the statement - at the origin of the log statement will be output. - -

If you are embedding this layout within an {@link - org.apache.log4j.net.SMTPAppender} then make sure to set the - LocationInfo option of that appender as well. - */ - public - void setLocationInfo(boolean flag) { - locationInfo = flag; - } - - /** - Returns the current value of the LocationInfo option. - */ - public - boolean getLocationInfo() { - return locationInfo; - } + // Print no location info by default + boolean locationInfo = false; + String title = "Log4J Log Messages"; /** - * Set the ConversionPattern option. This is the string which - * controls formatting and consists of a mix of literal content and - * conversion specifiers. + The LocationInfo option takes a boolean value. By + default, it is set to false which means there will be no location + information output by this layout. If the the option is set to + true, then the file name and line number of the statement + at the origin of the log statement will be output. + +

If you are embedding this layout within an {@link + org.apache.log4j.net.SMTPAppender} then make sure to set the + LocationInfo option of that appender as well. */ - public void setConversionPattern(String conversionPattern) { - pattern = conversionPattern; + public + void setLocationInfo(boolean flag) { + locationInfo = flag; } /** - * Returns the value of the ConversionPattern option. + Returns the current value of the LocationInfo option. */ - public String getConversionPattern() { - return pattern; + public + boolean getLocationInfo() { + return locationInfo; } /** - * Does not do anything as options become effective - */ - public void activateOptions() { - List converters = new ArrayList(); - List fields = new ArrayList(); - Map converterRegistry = null; - if(this.repository instanceof LoggerRepositoryEx) { - converterRegistry = (Map) ((LoggerRepositoryEx) repository).getObject(PATTERN_RULE_REGISTRY); - } - PatternParser.parse(pattern, converters, fields, - converterRegistry, PatternParser.getPatternLayoutRules(), getLogger()); - - patternConverters = new LoggingEventPatternConverter[converters.size()]; - patternFields = new FormattingInfo[converters.size()]; - - int i = 0; - Iterator converterIter = converters.iterator(); - Iterator fieldIter = fields.iterator(); - while(converterIter.hasNext()) { - Object converter = converterIter.next(); - if (converter instanceof LoggingEventPatternConverter) { - patternConverters[i] = (LoggingEventPatternConverter) converter; - chainHandlesThrowable |= patternConverters[i].handlesThrowable(); - } else { - patternConverters[i] = new LiteralPatternConverter(""); - } - if (fieldIter.hasNext()) { - patternFields[i] = (FormattingInfo) fieldIter.next(); - } else { - patternFields[i] = FormattingInfo.getDefault(); - } - i++; - } - } - + The Title option takes a String value. This option sets the + document title of the generated HTML document. - /** - * The Title option takes a String value. This option sets the - * document title of the generated HTML document. - * - *

- * Defaults to 'Log4J Log Messages'. - */ - public void setTitle(String title) { +

Defaults to 'Log4J Log Messages'. + */ + public + void setTitle(String title) { this.title = title; } /** - * Returns the current value of the Title option. - */ - public String getTitle() { + Returns the current value of the Title option. + */ + public + String getTitle() { return title; } - /** - * Returns the value of the internalCSS option. See {@link #setInternalCSS} - * method for details about the meaning of this option. - * - * @return boolean Value of internalCSS option - */ - public boolean isInternalCSS() { - return internalCSS; - } - - /** - * Set the value of the internalCSS option. If set to true, the generated HTML - * ouput will include an internal cascading style sheet. Otherwise, the - * generated HTML output will include a reference to an external CSS. - *

- * By default, internalCSS value is set to false, that is, - * by default, only a link to an external CSS file will be generated. - * - * @see #setURL2ExternalCSS - * - * @param internalCSS - */ - public void setInternalCSS(boolean internalCSS) { - this.internalCSS = internalCSS; + /** + Returns the content type output by this layout, i.e "text/html". + */ + public + String getContentType() { + return "text/html"; } - + /** - * Return the URL to the external CSS file. See {@link #setURL2ExternalCSS} - * method for details about the meaning of this option. - * - * @return URL to the external CSS file. - */ - public String getURL2ExternalCSS() { - return url2ExternalCSS; + No options to activate. + */ + public + void activateOptions() { } - /** - * Set the URL for the external CSS file. By default, the external - * CSS file is set to "http://logging.apache.org/log4j/docs/css/eventTable-1.0.css". - */ - public void setURL2ExternalCSS(String url2ExternalCSS) { - this.url2ExternalCSS = url2ExternalCSS; - } - - /** - * Returns the content type output by this layout, i.e "text/html". - */ - public String getContentType() { - return "text/html"; + + public + String format(LoggingEvent event) { + + if(sbuf.capacity() > MAX_CAPACITY) { + sbuf = new StringBuffer(BUF_SIZE); + } else { + sbuf.setLength(0); + } + + sbuf.append(Layout.LINE_SEP + "" + Layout.LINE_SEP); + + sbuf.append(""); + sbuf.append(event.timeStamp - LoggingEvent.getStartTime()); + sbuf.append("" + Layout.LINE_SEP); + + String escapedThread = Transform.escapeTags(event.getThreadName()); + sbuf.append(""); + sbuf.append(escapedThread); + sbuf.append("" + Layout.LINE_SEP); + + sbuf.append(""); + if (event.getLevel().equals(Level.DEBUG)) { + sbuf.append(""); + sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel()))); + sbuf.append(""); + } + else if(event.getLevel().isGreaterOrEqual(Level.WARN)) { + sbuf.append(""); + sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel()))); + sbuf.append(""); + } else { + sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel()))); + } + sbuf.append("" + Layout.LINE_SEP); + + String escapedLogger = Transform.escapeTags(event.getLoggerName()); + sbuf.append(""); + sbuf.append(escapedLogger); + sbuf.append("" + Layout.LINE_SEP); + + if(locationInfo) { + LocationInfo locInfo = event.getLocationInformation(); + sbuf.append(""); + sbuf.append(Transform.escapeTags(locInfo.getFileName())); + sbuf.append(':'); + sbuf.append(locInfo.getLineNumber()); + sbuf.append("" + Layout.LINE_SEP); + } + + sbuf.append(""); + sbuf.append(Transform.escapeTags(event.getRenderedMessage())); + sbuf.append("" + Layout.LINE_SEP); + sbuf.append("" + Layout.LINE_SEP); + + if (event.getNDC() != null) { + sbuf.append(""); + sbuf.append("NDC: " + Transform.escapeTags(event.getNDC())); + sbuf.append("" + Layout.LINE_SEP); + } + + String[] s = event.getThrowableStrRep(); + if(s != null) { + sbuf.append(""); + appendThrowableAsHTML(s, sbuf); + sbuf.append("" + Layout.LINE_SEP); + } + + return sbuf.toString(); } - void appendThrowableAsHTML(final String[] s, final StringBuffer sbuf) { - if (s != null) { + void appendThrowableAsHTML(String[] s, StringBuffer sbuf) { + if(s != null) { int len = s.length; - if (len == 0) { + if(len == 0) { return; - } + } sbuf.append(Transform.escapeTags(s[0])); sbuf.append(Layout.LINE_SEP); - for (int i = 1; i < len; i++) { - sbuf.append(TRACE_PREFIX); - sbuf.append(Transform.escapeTags(s[i])); - sbuf.append(Layout.LINE_SEP); + for(int i = 1; i < len; i++) { + sbuf.append(TRACE_PREFIX); + sbuf.append(Transform.escapeTags(s[i])); + sbuf.append(Layout.LINE_SEP); } } } /** - * Returns appropriate HTML headers. - */ - public String getHeader() { + Returns appropriate HTML headers. + */ + public + String getHeader() { StringBuffer sbuf = new StringBuffer(); - sbuf.append(""); - sbuf.append(Layout.LINE_SEP); - sbuf.append(""); - sbuf.append(Layout.LINE_SEP); - sbuf.append(""); - sbuf.append(Layout.LINE_SEP); - sbuf.append(""); - sbuf.append(title); - sbuf.append(""); - sbuf.append(Layout.LINE_SEP); - if(internalCSS) { - getInternalCSS(sbuf); - } else { - sbuf.append(""); - } - sbuf.append(Layout.LINE_SEP); - sbuf.append(""); - sbuf.append(Layout.LINE_SEP); - sbuf.append(""); - sbuf.append(Layout.LINE_SEP); - - sbuf.append("


"); - sbuf.append(Layout.LINE_SEP); - - sbuf.append("Log session start time "); - sbuf.append(new java.util.Date()); - sbuf.append("
"); - sbuf.append(Layout.LINE_SEP); - sbuf.append("
"); - sbuf.append(Layout.LINE_SEP); - sbuf.append(""); - sbuf.append(Layout.LINE_SEP); - - - sbuf.append(""); - sbuf.append(Layout.LINE_SEP); - for (int i = 0; i < patternConverters.length; i++) { - PatternConverter c = patternConverters[i]; - sbuf.append(""); - sbuf.append(Layout.LINE_SEP); + sbuf.append("" + Layout.LINE_SEP); + sbuf.append("" + Layout.LINE_SEP); + sbuf.append("" + Layout.LINE_SEP); + sbuf.append("" + title + "" + Layout.LINE_SEP); + sbuf.append("" + Layout.LINE_SEP); + sbuf.append("" + Layout.LINE_SEP); + sbuf.append("" + Layout.LINE_SEP); + sbuf.append("
" + Layout.LINE_SEP); + sbuf.append("Log session start time " + new java.util.Date() + "
" + Layout.LINE_SEP); + sbuf.append("
" + Layout.LINE_SEP); + sbuf.append("
"); - sbuf.append(c.getName()); - sbuf.append("
" + Layout.LINE_SEP); + sbuf.append("" + Layout.LINE_SEP); + sbuf.append("" + Layout.LINE_SEP); + sbuf.append("" + Layout.LINE_SEP); + sbuf.append("" + Layout.LINE_SEP); + sbuf.append("" + Layout.LINE_SEP); + if(locationInfo) { + sbuf.append("" + Layout.LINE_SEP); } - sbuf.append(""); - sbuf.append(Layout.LINE_SEP); - + sbuf.append("" + Layout.LINE_SEP); + sbuf.append("" + Layout.LINE_SEP); return sbuf.toString(); } /** - * Returns the appropriate HTML footers. - */ - public String getFooter() { + Returns the appropriate HTML footers. + */ + public + String getFooter() { StringBuffer sbuf = new StringBuffer(); - sbuf.append("
TimeThreadLevelCategoryFile:Line
Message
"); - sbuf.append(Layout.LINE_SEP); - sbuf.append("
"); - sbuf.append(Layout.LINE_SEP); + sbuf.append("" + Layout.LINE_SEP); + sbuf.append("
" + Layout.LINE_SEP); sbuf.append(""); return sbuf.toString(); } /** - * The HTML layout handles the throwable contained in logging events. Hence, - * this method return false. - */ - public boolean ignoresThrowable() { + The HTML layout handles the throwable contained in logging + events. Hence, this method return false. */ + public + boolean ignoresThrowable() { return false; } - - /** - * {@inheritDoc} - */ - public String format(final LoggingEvent event) { - boolean oddCopy; - synchronized(this) { - odd = !odd; - oddCopy = odd; - } - - String level = event.getLevel().toString().toLowerCase(); - - StringBuffer buf = new StringBuffer(); - buf.append(Layout.LINE_SEP); - buf.append(""); - } else { - buf.append(" even\">"); - } - buf.append(Layout.LINE_SEP); - - for(int i = 0; i < patternConverters.length; i++) { - PatternConverter c = patternConverters[i]; - buf.append(""); - int fieldStart = buf.length(); - c.format(event, buf); - patternFields[i].format(fieldStart, buf); - buf.append(""); - buf.append(Layout.LINE_SEP); - } - buf.append(""); - buf.append(Layout.LINE_SEP); - - // if the pattern chain handles throwables then no need to do it again here. - if(!chainHandlesThrowable) { - String[] s = event.getThrowableStrRep(); - if (s != null) { - buf.append(""); - appendThrowableAsHTML(s, buf); - buf.append(""); - buf.append(Layout.LINE_SEP); - } - } - return buf.toString(); - } - - /** - * Generate an internal CSS file. - * @param buf The StringBuffer where the CSS file will be placed. - */ - void getInternalCSS(StringBuffer buf) { - - buf.append(""); - buf.append(Layout.LINE_SEP); - - } } diff --git a/src/main/java/org/apache/log4j/Hierarchy.java b/src/main/java/org/apache/log4j/Hierarchy.java index db211a3054..6c82c98ff1 100644 --- a/src/main/java/org/apache/log4j/Hierarchy.java +++ b/src/main/java/org/apache/log4j/Hierarchy.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,42 +15,32 @@ * limitations under the License. */ - // WARNING This class MUST not have references to the Category or -// WARNING RootLogger classes in its static initiliazation neither +// WARNING RootCategory classes in its static initiliazation neither // WARNING directly nor indirectly. + +// Contributors: +// Luke Blanshard +// Mario Schomburg - IBM Global Services/Germany +// Anders Kristensen +// Igor Poteryaev + package org.apache.log4j; -import org.apache.log4j.helpers.IntializationUtil; -import org.apache.log4j.helpers.LogLog; -import org.apache.log4j.or.ObjectRenderer; -import org.apache.log4j.or.RendererMap; -import org.apache.log4j.plugins.PluginRegistry; -import org.apache.log4j.scheduler.Scheduler; -import org.apache.log4j.spi.ErrorItem; -import org.apache.log4j.spi.LoggerEventListener; -import org.apache.log4j.spi.LoggerFactory; -import org.apache.log4j.spi.LoggerRepositoryEx; -import org.apache.log4j.spi.LoggerRepositoryEventListener; -import org.apache.log4j.spi.RendererSupport; -import org.apache.log4j.spi.RootLogger; -import org.apache.log4j.spi.HierarchyEventListener; -import org.apache.log4j.spi.HierarchyEventListenerAdapter; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; import java.util.Hashtable; -import java.util.List; -import java.util.Map; +import java.util.Enumeration; import java.util.Vector; - -// Contributors: Luke Blanshard -// Mario Schomburg - IBM Global Services/Germany -// Anders Kristensen -// Igor Poteryaev - +import org.apache.log4j.spi.LoggerFactory; +import org.apache.log4j.spi.HierarchyEventListener; +import org.apache.log4j.spi.LoggerRepository; +import org.apache.log4j.spi.RendererSupport; +import org.apache.log4j.or.RendererMap; +import org.apache.log4j.or.ObjectRenderer; +import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.spi.ThrowableRendererSupport; +import org.apache.log4j.spi.ThrowableRenderer; /** This class is specialized in retrieving loggers by name and also @@ -71,210 +61,57 @@ themselves to the previously created provision node. @author Ceki Gülcü - @author Mark Womack */ -public class Hierarchy implements LoggerRepositoryEx, RendererSupport { +public class Hierarchy implements LoggerRepository, RendererSupport, ThrowableRendererSupport { + + private LoggerFactory defaultFactory; + private Vector listeners; - /** - * Logger factory. - */ - private LoggerFactory loggerFactory; - /** - * List of repository event listeners. - */ - private final ArrayList repositoryEventListeners; - /** - * List of logger event listeners. - */ - private final ArrayList loggerEventListeners; - /** - * Name of hierarchy. - */ - String name; - /** - * Loggers by name. - */ Hashtable ht; - /** - * Root logger. - */ Logger root; - /** - * Map of ObjectRenderer by Class. - */ RendererMap rendererMap; - /** - * Numeric value for threshold. - */ + int thresholdInt; - /** - * Threshold. - */ Level threshold; - /** - * Plug in registry. - */ - PluginRegistry pluginRegistry; - /** - * Properties. - */ - Map properties; - /** - * Scheduler. - */ - private Scheduler scheduler; - - /** The repository can also be used as an object store - * for various objects used by log4j components. - */ - private Map objectMap; - /** - * The internal logger used by this instance of - * Hierarchy for its own reporting. - */ - private Logger myLogger; - - /** - * Error list. - */ - private List errorList = new Vector(); - - /** - * True if no appender warning has already been issued. - */ boolean emittedNoAppenderWarning = false; - /** - * True if hierarchy has not been modified. - */ - boolean pristine = true; + boolean emittedNoResourceBundleWarning = false; + + private ThrowableRenderer throwableRenderer = null; /** - Constructs a new logger hierarchy. + Create a new logger hierarchy. - @param rootLogger The root of the new hierarchy. + @param root The root of the new hierarchy. */ - public Hierarchy(final Logger rootLogger) { + public + Hierarchy(Logger root) { ht = new Hashtable(); - repositoryEventListeners = new ArrayList(1); - loggerEventListeners = new ArrayList(1); - this.root = rootLogger; - this.objectMap = new HashMap(); + listeners = new Vector(1); + this.root = root; // Enable all level levels by default. setThreshold(Level.ALL); this.root.setHierarchy(this); rendererMap = new RendererMap(); - rendererMap.setLoggerRepository(this); - properties = new Hashtable(); - loggerFactory = new DefaultLoggerFactory(); - } - - /** - * Constructs a new logger hierarchy with a default {@link RootLogger}. - */ - public Hierarchy() { - this(new RootLogger()); + defaultFactory = new DefaultCategoryFactory(); } /** Add an object renderer for a specific class. - @param classToRender class to render - @param or renderer */ - public void addRenderer(final Class classToRender, - final ObjectRenderer or) { + public + void addRenderer(Class classToRender, ObjectRenderer or) { rendererMap.put(classToRender, or); } - /** - Add a {@link LoggerRepositoryEventListener} to the repository. The - listener will be called when repository events occur. - @param listener listener - @since 1.3*/ - public void addLoggerRepositoryEventListener( - final LoggerRepositoryEventListener listener) { - synchronized (repositoryEventListeners) { - if (repositoryEventListeners.contains(listener)) { - getMyLogger().warn( - "Ignoring attempt to add a previously " - + "registered LoggerRepositoryEventListener."); - } else { - repositoryEventListeners.add(listener); - } - } - } - - /** - * Gets logger to be used for internal diagnostic messages. - * @return logger - */ - private Logger getMyLogger() { - if (myLogger == null) { - myLogger = getLogger(this.getClass().getName()); - } - return myLogger; - } - - /** - Remove a {@link LoggerRepositoryEventListener} from the repository. - @param listener listener - @since 1.3*/ - public void removeLoggerRepositoryEventListener( - final LoggerRepositoryEventListener listener) { - synchronized (repositoryEventListeners) { - if (!repositoryEventListeners.contains(listener)) { - getMyLogger().warn( - "Ignoring attempt to remove a " - + "non-registered LoggerRepositoryEventListener."); - } else { - repositoryEventListeners.remove(listener); - } - } - } - - /** - Add a {@link LoggerEventListener} to the repository. The listener - will be called when repository events occur. - @param listener listener - @since 1.3 - */ - public void addLoggerEventListener(final LoggerEventListener listener) { - synchronized (loggerEventListeners) { - if (loggerEventListeners.contains(listener)) { - getMyLogger().warn( - "Ignoring attempt to add a previously registerd LoggerEventListener."); - } else { - loggerEventListeners.add(listener); - } - } - } - - /** - Add a {@link org.apache.log4j.spi.HierarchyEventListener} - event to the repository. - @param listener listener - @deprecated Superceded by addLoggerEventListener - */ - public - void addHierarchyEventListener(final HierarchyEventListener listener) { - addLoggerEventListener(new HierarchyEventListenerAdapter(listener)); - } - - - /** - Remove a {@link LoggerEventListener} from the repository. - @param listener listener to be removed - @since 1.3*/ - public void removeLoggerEventListener(final LoggerEventListener listener) { - synchronized (loggerEventListeners) { - if (!loggerEventListeners.contains(listener)) { - getMyLogger().warn( - "Ignoring attempt to remove a non-registered LoggerEventListener."); - } else { - loggerEventListeners.remove(listener); - } + public + void addHierarchyEventListener(HierarchyEventListener listener) { + if(listeners.contains(listener)) { + LogLog.warn("Ignoring attempt to add an existent listener."); + } else { + listeners.addElement(listener); } } @@ -287,21 +124,20 @@ public void removeLoggerEventListener(final LoggerEventListener listener) { invoking this method. @since 0.9.0 */ - public void clear() { + public + void clear() { //System.out.println("\n\nAbout to clear internal hash table."); ht.clear(); } - /** - * Issue warning that there are no appenders in hierarchy. - * @param cat logger, not currently used. - */ - public void emitNoAppenderWarning(final Category cat) { + public + void emitNoAppenderWarning(Category cat) { // No appenders in hierarchy, warn user only once. - if (!this.emittedNoAppenderWarning) { - //LogLog.warn( - // "No appenders could be found for logger (" + cat.getName() + ")."); - //LogLog.warn("Please initialize the log4j system properly."); + if(!this.emittedNoAppenderWarning) { + LogLog.warn("No appenders could be found for logger (" + + cat.getName() + ")."); + LogLog.warn("Please initialize the log4j system properly."); + LogLog.warn("See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info."); this.emittedNoAppenderWarning = true; } } @@ -310,224 +146,77 @@ public void emitNoAppenderWarning(final Category cat) { Check if the named logger exists in the hierarchy. If so return its reference, otherwise returns null. - @param loggerName The name of the logger to search for. - @return true if logger exists. - */ - public Logger exists(final String loggerName) { - Object o = ht.get(new CategoryKey(loggerName)); + @param name The name of the logger to search for. - if (o instanceof Logger) { + */ + public + Logger exists(String name) { + Object o = ht.get(new CategoryKey(name)); + if(o instanceof Logger) { return (Logger) o; } else { return null; } } - /** - * Return the name of this hierarchy. - * @return name of hierarchy - */ - public String getName() { - return name; - } - - /** - * Set the name of this repository. - * - * Note that once named, a repository cannot be rerenamed. - * @since 1.3 - * @param repoName name of hierarchy - */ - public void setName(final String repoName) { - if (name == null) { - name = repoName; - } else if (!name.equals(repoName)) { - throw new IllegalStateException( - "Repository [" + name + "] cannot be renamed as [" + repoName + "]."); - } - } - - /** - * {@inheritDoc} - */ - public Map getProperties() { - return properties; - } - - /** - * {@inheritDoc} - */ - public String getProperty(final String key) { - return (String) properties.get(key); - } - - /** - * Set a property by key and value. The property will be shared by all - * events in this repository. - * @param key property name - * @param value property value - */ - public void setProperty(final String key, - final String value) { - properties.put(key, value); - } - /** The string form of {@link #setThreshold(Level)}. - @param levelStr symbolic name for level */ - public void setThreshold(final String levelStr) { + public + void setThreshold(String levelStr) { Level l = Level.toLevel(levelStr, null); - - if (l != null) { + if(l != null) { setThreshold(l); } else { - getMyLogger().warn("Could not convert [" + levelStr + "] to Level."); + LogLog.warn("Could not convert ["+levelStr+"] to Level."); } } + /** Enable logging for logging requests with level l or higher. By default all levels are enabled. @param l The minimum level for which logging requests are sent to their appenders. */ - public void setThreshold(final Level l) { - if (l != null) { + public + void setThreshold(Level l) { + if(l != null) { thresholdInt = l.level; threshold = l; } } - /** - * {@inheritDoc} - * @since 1.3 - */ - public PluginRegistry getPluginRegistry() { - if (pluginRegistry == null) { - pluginRegistry = new PluginRegistry(this); - } - return pluginRegistry; - } - - - /** - Requests that a appender added event be sent to any registered - {@link LoggerEventListener}. - @param logger The logger to which the appender was added. - @param appender The appender added to the logger. - */ - public void fireAddAppenderEvent(final Category logger, - final Appender appender) { - if (logger instanceof Logger) { - fireAddAppenderEvent((Logger) logger, appender); - } - } - - /** - Requests that a appender added event be sent to any registered - {@link LoggerEventListener}. - @param logger The logger to which the appender was added. - @param appender The appender added to the logger. - @since 1.3 - */ - public void fireAddAppenderEvent(final Logger logger, - final Appender appender) { - ArrayList list = copyListenerList(loggerEventListeners); - int size = list.size(); - - for (int i = 0; i < size; i++) { - ((LoggerEventListener) list.get(i)). - appenderAddedEvent(logger, appender); - } - } - - - /** - Requests that a appender removed event be sent to any registered - {@link LoggerEventListener}. - @param logger The logger from which the appender was removed. - @param appender The appender removed from the logger. - */ - public void fireRemoveAppenderEvent(final Category logger, - final Appender appender) { - if (logger instanceof Logger) { - fireRemoveAppenderEvent((Logger) logger, appender); - } - } - - /** - Requests that a appender removed event be sent to any registered - {@link LoggerEventListener}. - @param logger The logger from which the appender was removed. - @param appender The appender removed from the logger. - @since 1.3*/ - public void fireRemoveAppenderEvent(final Logger logger, - final Appender appender) { - ArrayList list = copyListenerList(loggerEventListeners); - int size = list.size(); - - for (int i = 0; i < size; i++) { - ((LoggerEventListener) list.get(i)).appenderRemovedEvent( - logger, appender); - } - } - - /** - Requests that a level changed event be sent to any registered - {@link LoggerEventListener}. - @param logger The logger which changed levels. - @since 1.3*/ - public void fireLevelChangedEvent(final Logger logger) { - ArrayList list = copyListenerList(loggerEventListeners); - int size = list.size(); - - for (int i = 0; i < size; i++) { - ((LoggerEventListener) list.get(i)).levelChangedEvent(logger); - } - } - - /** - Requests that a configuration changed event be sent to any registered - {@link LoggerRepositoryEventListener}. - @since 1.3*/ - public void fireConfigurationChangedEvent() { - ArrayList list = copyListenerList(repositoryEventListeners); - int size = list.size(); - - for (int i = 0; i < size; i++) { - ((LoggerRepositoryEventListener) list.get(i)).configurationChangedEvent( - this); + public + void fireAddAppenderEvent(Category logger, Appender appender) { + if(listeners != null) { + int size = listeners.size(); + HierarchyEventListener listener; + for(int i = 0; i < size; i++) { + listener = (HierarchyEventListener) listeners.elementAt(i); + listener.addAppenderEvent(logger, appender); + } } } - /** - Returns a copy of the given listener vector. - @param list original list - @return copy of list - */ - private ArrayList copyListenerList(final ArrayList list) { - ArrayList listCopy = null; - - synchronized (list) { - int size = list.size(); - listCopy = new ArrayList(size); - - for (int x = 0; x < size; x++) { - listCopy.add(list.get(x)); + void fireRemoveAppenderEvent(Category logger, Appender appender) { + if(listeners != null) { + int size = listeners.size(); + HierarchyEventListener listener; + for(int i = 0; i < size; i++) { + listener = (HierarchyEventListener) listeners.elementAt(i); + listener.removeAppenderEvent(logger, appender); } } - - return listCopy; } /** Returns a {@link Level} representation of the enable state. - @return current threshold level @since 1.2 */ - public Level getThreshold() { + public + Level getThreshold() { return threshold; } @@ -536,7 +225,6 @@ public Level getThreshold() { threshold. @since 1.2 */ - //public //int getThresholdInt() { // return thresholdInt; @@ -551,69 +239,58 @@ public Level getThreshold() { returned. Otherwise, a new logger will be instantiated and then linked with its existing ancestors as well as children. - @param loggerName The name of the logger to retrieve. - @return logger + @param name The name of the logger to retrieve. - */ - public Logger getLogger(final String loggerName) { - return getLogger(loggerName, loggerFactory); + */ + public + Logger getLogger(String name) { + return getLogger(name, defaultFactory); } - /** - Return a new logger instance named as the first parameter using - factory. + /** + Return a new logger instance named as the first parameter using + factory. -

If a logger of that name already exists, then it will be - returned. Otherwise, a new logger will be instantiated by the - factory parameter and linked with its existing - ancestors as well as children. +

If a logger of that name already exists, then it will be + returned. Otherwise, a new logger will be instantiated by the + factory parameter and linked with its existing + ancestors as well as children. - @param loggerName The name of the logger to retrieve. - @param factory The factory that will make the new logger instance. - @return logger + @param name The name of the logger to retrieve. + @param factory The factory that will make the new logger instance. - */ - public Logger getLogger(final String loggerName, - final LoggerFactory factory) { + */ + public + Logger getLogger(String name, LoggerFactory factory) { //System.out.println("getInstance("+name+") called."); - CategoryKey key = new CategoryKey(loggerName); - - + CategoryKey key = new CategoryKey(name); // Synchronize to prevent write conflicts. Read conflicts (in // getChainedLevel method) are possible only if variable // assignments are non-atomic. Logger logger; - synchronized (ht) { + synchronized(ht) { Object o = ht.get(key); - - if (o == null) { - LogLog.debug( - "Creating new logger [" + loggerName - + "] in repository [" + getName() + "]."); - logger = factory.makeNewLoggerInstance(loggerName); - logger.setHierarchy(this); - ht.put(key, logger); - updateParents(logger); - - return logger; - } else if (o instanceof Logger) { - LogLog.debug( - "Returning existing logger [" + loggerName - + "] in repository [" + getName() + "]."); - return (Logger) o; + if(o == null) { + logger = factory.makeNewLoggerInstance(name); + logger.setHierarchy(this); + ht.put(key, logger); + updateParents(logger); + return logger; + } else if(o instanceof Logger) { + return (Logger) o; } else if (o instanceof ProvisionNode) { - //System.out.println("("+name+") ht.get(this) returned ProvisionNode"); - logger = factory.makeNewLoggerInstance(loggerName); - logger.setHierarchy(this); - ht.put(key, logger); - updateChildren((ProvisionNode) o, logger); - updateParents(logger); - - return logger; - } else { - // It should be impossible to arrive here - return null; // but let's keep the compiler happy. + //System.out.println("("+name+") ht.get(this) returned ProvisionNode"); + logger = factory.makeNewLoggerInstance(name); + logger.setHierarchy(this); + ht.put(key, logger); + updateChildren((ProvisionNode) o, logger); + updateParents(logger); + return logger; + } + else { + // It should be impossible to arrive here + return null; // but let's keep the compiler happy. } } } @@ -623,84 +300,70 @@ public Logger getLogger(final String loggerName, an {@link java.util.Enumeration Enumeration}.

The root logger is not included in the returned - {@link Enumeration}. - @return enumerator of current loggers - */ - public Enumeration getCurrentLoggers() { + {@link Enumeration}. */ + public + Enumeration getCurrentLoggers() { // The accumlation in v is necessary because not all elements in // ht are Logger objects as there might be some ProvisionNodes // as well. Vector v = new Vector(ht.size()); Enumeration elems = ht.elements(); - - while (elems.hasMoreElements()) { + while(elems.hasMoreElements()) { Object o = elems.nextElement(); - - if (o instanceof Logger) { - v.addElement(o); + if(o instanceof Logger) { + v.addElement(o); } } - return v.elements(); } /** - * Return the the list of previously encoutered {@link ErrorItem error items}. - * @return list of errors - */ - public List getErrorList() { - return errorList; - } - - /** - * Add an error item to the list of previously encountered errors. - * @param errorItem error to add to list of errors. - * @since 1.3 - */ - public void addErrorItem(final ErrorItem errorItem) { - getErrorList().add(errorItem); - } - - /** - * Get enumerator over current loggers. - * @return enumerator over current loggers @deprecated Please use {@link #getCurrentLoggers} instead. */ - public Enumeration getCurrentCategories() { + public + Enumeration getCurrentCategories() { return getCurrentLoggers(); } + /** Get the renderer map for this hierarchy. - @return renderer map */ - public RendererMap getRendererMap() { + public + RendererMap getRendererMap() { return rendererMap; } + /** Get the root of this hierarchy. @since 0.9.0 - @return root of hierarchy */ - public Logger getRootLogger() { + public + Logger getRootLogger() { return root; } /** This method will return true if this repository is - disabled for level value passed as parameter and + disabled for level object passed as parameter and false otherwise. See also the {@link - #setThreshold(Level) threshold} method. - @param level numeric value for level. - @return true if disabled for specified level - */ - public boolean isDisabled(final int level) { + #setThreshold(Level) threshold} emthod. */ + public + boolean isDisabled(int level) { return thresholdInt > level; } + /** + @deprecated Deprecated with no replacement. + */ + public + void overrideAsNeeded(String override) { + LogLog.warn("The Hiearchy.overrideAsNeeded method has been deprecated."); + } + /** Reset all values contained in this hierarchy instance to their default. This removes all appenders from all categories, sets @@ -715,63 +378,65 @@ public boolean isDisabled(final int level) { block all logging until it is completed.

@since 0.8.5 */ - public void resetConfiguration() { + public + void resetConfiguration() { + getRootLogger().setLevel(Level.DEBUG); root.setResourceBundle(null); setThreshold(Level.ALL); - // the synchronization is needed to prevent JDK 1.2.x hashtable // surprises - synchronized (ht) { - shutdown(true); // nested locks are OK + synchronized(ht) { + shutdown(); // nested locks are OK Enumeration cats = getCurrentLoggers(); - - while (cats.hasMoreElements()) { - Logger c = (Logger) cats.nextElement(); - c.setLevel(null); - c.setAdditivity(true); - c.setResourceBundle(null); + while(cats.hasMoreElements()) { + Logger c = (Logger) cats.nextElement(); + c.setLevel(null); + c.setAdditivity(true); + c.setResourceBundle(null); } } - rendererMap.clear(); + throwableRenderer = null; + } - // inform the listeners that the configuration has been reset - ArrayList list = copyListenerList(repositoryEventListeners); - int size = list.size(); + /** + Does nothing. - for (int i = 0; i < size; i++) { - ((LoggerRepositoryEventListener) list.get(i)).configurationResetEvent( - this); - } + @deprecated Deprecated with no replacement. + */ + public + void setDisableOverride(String override) { + LogLog.warn("The Hiearchy.setDisableOverride method has been deprecated."); } + + /** Used by subclasses to add a renderer to the hierarchy passed as parameter. - @param renderedClass class - @param renderer object used to render class. */ - public void setRenderer(final Class renderedClass, - final ObjectRenderer renderer) { + public + void setRenderer(Class renderedClass, ObjectRenderer renderer) { rendererMap.put(renderedClass, renderer); } - /** - * {@inheritDoc} - */ - public boolean isPristine() { - return pristine; + /** + * {@inheritDoc} + */ + public void setThrowableRenderer(final ThrowableRenderer renderer) { + throwableRenderer = renderer; } - /** - * {@inheritDoc} - */ - public void setPristine(final boolean state) { - pristine = state; + /** + * {@inheritDoc} + */ + public ThrowableRenderer getThrowableRenderer() { + return throwableRenderer; } + /** Shutting down a hierarchy will safely close and remove all appenders in all categories including the root logger. @@ -786,61 +451,33 @@ public void setPristine(final boolean state) { configurations where a regular appender is attached to a logger and again to a nested appender. - @since 1.0 */ - public void shutdown() { - shutdown(false); - } - /** - * Shutdown hierarchy. - * @param doingReset true is resetting hierarchy - */ - private void shutdown(final boolean doingReset) { - - // stop this repo's scheduler if it has one - if (scheduler != null) { - scheduler.shutdown(); - scheduler = null; - } - - // let listeners know about shutdown if this is - // not being done as part of a reset. - if (!doingReset) { - ArrayList list = copyListenerList(repositoryEventListeners); - int size = list.size(); - - for (int i = 0; i < size; i++) { - ((LoggerRepositoryEventListener) list.get(i)).shutdownEvent(this); - } - } - - Logger rootLogger = getRootLogger(); + @since 1.0 */ + public + void shutdown() { + Logger root = getRootLogger(); // begin by closing nested appenders - rootLogger.closeNestedAppenders(); + root.closeNestedAppenders(); - synchronized (ht) { + synchronized(ht) { Enumeration cats = this.getCurrentLoggers(); - - while (cats.hasMoreElements()) { - Logger c = (Logger) cats.nextElement(); - c.closeNestedAppenders(); + while(cats.hasMoreElements()) { + Logger c = (Logger) cats.nextElement(); + c.closeNestedAppenders(); } // then, remove all appenders - rootLogger.removeAllAppenders(); + root.removeAllAppenders(); cats = this.getCurrentLoggers(); - - while (cats.hasMoreElements()) { - Logger c = (Logger) cats.nextElement(); - c.removeAllAppenders(); + while(cats.hasMoreElements()) { + Logger c = (Logger) cats.nextElement(); + c.removeAllAppenders(); } } - - // log4j self configure - IntializationUtil.log4jInternalConfiguration(this); } + /** This method loops through all the *potential* parents of 'cat'. There 3 possible cases: @@ -860,50 +497,45 @@ private void shutdown(final boolean doingReset) { 3) There entry is of type ProvisionNode for this potential parent. We add 'cat' to the list of children for this potential parent. - @param cat logger whose parents are updated */ - private void updateParents(final Logger cat) { - String loggerName = cat.name; - int length = loggerName.length(); + final + private + void updateParents(Logger cat) { + String name = cat.name; + int length = name.length(); boolean parentFound = false; - //System.out.println("UpdateParents called for " + name); - // if name = "w.x.y.z", - // loop through "w.x.y", "w.x" and "w", but not "w.x.y.z" - for ( - int i = loggerName.lastIndexOf('.', length - 1); i >= 0; - i = loggerName.lastIndexOf('.', i - 1)) { - String substr = loggerName.substring(0, i); + + // if name = "w.x.y.z", loop thourgh "w.x.y", "w.x" and "w", but not "w.x.y.z" + for(int i = name.lastIndexOf('.', length-1); i >= 0; + i = name.lastIndexOf('.', i-1)) { + String substr = name.substring(0, i); //System.out.println("Updating parent : " + substr); CategoryKey key = new CategoryKey(substr); // simple constructor Object o = ht.get(key); - // Create a provision node for a future parent. - if (o == null) { - //System.out.println("No parent "+substr+" found. Creating ProvisionNode."); - ProvisionNode pn = new ProvisionNode(cat); - ht.put(key, pn); - } else if (o instanceof Logger) { - parentFound = true; - cat.parent = (Logger) o; - - //System.out.println("Linking " + cat.name + " -> " + ((Logger) o).name); - break; // no need to update the ancestors of the closest ancestor - } else if (o instanceof ProvisionNode) { - ((ProvisionNode) o).addElement(cat); + if(o == null) { + //System.out.println("No parent "+substr+" found. Creating ProvisionNode."); + ProvisionNode pn = new ProvisionNode(cat); + ht.put(key, pn); + } else if(o instanceof Category) { + parentFound = true; + cat.parent = (Category) o; + //System.out.println("Linking " + cat.name + " -> " + ((Category) o).name); + break; // no need to update the ancestors of the closest ancestor + } else if(o instanceof ProvisionNode) { + ((ProvisionNode) o).addElement(cat); } else { - Exception e = - new IllegalStateException( - "unexpected object type " + o.getClass() + " in ht."); - e.printStackTrace(); + Exception e = new IllegalStateException("unexpected object type " + + o.getClass() + " in ht."); + e.printStackTrace(); } } - // If we could not find any existing parents, then link with root. - if (!parentFound) { - cat.parent = root; + if(!parentFound) { + cat.parent = root; } } @@ -918,80 +550,29 @@ private void updateParents(final Logger cat) { If the child 'c' has been already linked to a child of 'cat' then there is no need to update 'c'. - Otherwise, we set cat's parent field to c's parent and set - c's parent field to cat. - @param pn provisional node - @param logger parent logger + Otherwise, we set cat's parent field to c's parent and set + c's parent field to cat. */ - private void updateChildren(final ProvisionNode pn, - final Logger logger) { + final + private + void updateChildren(ProvisionNode pn, Logger logger) { //System.out.println("updateChildren called for " + logger.name); final int last = pn.size(); - for (int i = 0; i < last; i++) { + for(int i = 0; i < last; i++) { Logger l = (Logger) pn.elementAt(i); - - //System.out.println("Updating child " +p.name); + // Unless this child already points to a correct (lower) parent, // make cat.parent point to l.parent and l.parent to cat. - if (!l.parent.name.startsWith(logger.name)) { - logger.parent = l.parent; - l.parent = logger; + if(!l.parent.name.startsWith(logger.name)) { + logger.parent = l.parent; + l.parent = logger; } } } - /** - * Return this repository's own scheduler. - * The scheduler is lazily instantiated. - * @return this repository's own scheduler. - */ - public Scheduler getScheduler() { - if (scheduler == null) { - scheduler = new Scheduler(); - scheduler.setDaemon(true); - scheduler.start(); - } - return scheduler; - } - - /** - * Puts object by key. - * @param key key, may not be null. - * @param value object to associate with key. - */ - public void putObject(final String key, - final Object value) { - objectMap.put(key, value); - } - - /** - * Get object by key. - * @param key key, may not be null. - * @return object associated with key or null. - */ - public Object getObject(final String key) { - return objectMap.get(key); - } - /** - * Set logger factory. - * @param factory logger factory. - */ - public void setLoggerFactory(final LoggerFactory factory) { - if (factory == null) { - throw new NullPointerException(); - } - this.loggerFactory = factory; - } +} - /** - * Get logger factory. - * @return logger factory. - */ - public LoggerFactory getLoggerFactory() { - return loggerFactory; - } -} diff --git a/src/main/java/org/apache/log4j/Layout.java b/src/main/java/org/apache/log4j/Layout.java index e33d8664db..63015aa0f3 100644 --- a/src/main/java/org/apache/log4j/Layout.java +++ b/src/main/java/org/apache/log4j/Layout.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,110 +17,73 @@ package org.apache.log4j; -import java.io.CharArrayWriter; -import java.io.IOException; -import java.io.Writer; - -import org.apache.log4j.spi.ComponentBase; -import org.apache.log4j.spi.LoggingEvent; import org.apache.log4j.spi.OptionHandler; - +import org.apache.log4j.spi.LoggingEvent; /** Extend this abstract class to create your own log layout format. - + @author Ceki Gülcü - @author Chris Nokes */ -public abstract class Layout extends ComponentBase implements OptionHandler { + +public abstract class Layout implements OptionHandler { + // Note that the line.separator property can be looked up even by // applets. - public static final String LINE_SEP = System.getProperty("line.separator"); - public static final int LINE_SEP_LEN = LINE_SEP.length(); - - String header; - String footer; + public final static String LINE_SEP = System.getProperty("line.separator"); + public final static int LINE_SEP_LEN = LINE_SEP.length(); + - protected boolean ignoresThrowable = true; - /** - * Implement this method to create your own layout format. - * */ - public abstract String format(LoggingEvent event); + Implement this method to create your own layout format. + */ + abstract + public + String format(LoggingEvent event); /** Returns the content type output by this layout. The base class - returns "text/plain". + returns "text/plain". */ - public String getContentType() { + public + String getContentType() { return "text/plain"; } /** - * Returns the header for the layout format. There is no default header. - * */ - public String getHeader() { - return header; + Returns the header for the layout format. The base class returns + null. */ + public + String getHeader() { + return null; } /** - * Returns the footer for the layout format. There is no default footer. - */ - public String getFooter() { - return footer; + Returns the footer for the layout format. The base class returns + null. */ + public + String getFooter() { + return null; } - - /** - * If the layout handles the throwable object contained within - * {@link LoggingEvent}, then the layout should return false. - * Otherwise, if the layout ignores throwable object, then the layout should - * return true. - * - *

By default, {@link SimpleLayout}, {@link TTCCLayout}, {@link - * PatternLayout} all return true. The {@link - * org.apache.log4j.xml.XMLLayout} returns false. - * - *

As of log4j version 1.3, ignoresThrowable is a settable property. Thus, - * you can override a layout's default setting. - * - * @since 0.8.4 - * */ - public boolean ignoresThrowable() { - return ignoresThrowable; - } - /** - * - * @since 1.3 - * @param ignoresThrowable - */ - public void setIgnoresThrowable(boolean ignoresThrowable) { - this.ignoresThrowable = ignoresThrowable; - } - - - /** - * Set the footer. Note that some layout have their own footers and may choose - * to ignote the footer set here. - * - * @param footer the footer - * @since 1.3 - */ - public void setFooter(String footer) { - this.footer = footer; - } /** - * Set the header. Note that some layout have their own headers and may choose - * to ignote the header set here. - * - * @param header the header - * @since 1.3 - */ - public void setHeader(String header) { - this.header = header; - } - + If the layout handles the throwable object contained within + {@link LoggingEvent}, then the layout should return + false. Otherwise, if the layout ignores throwable + object, then the layout should return true. + If ignoresThrowable is true, the appender is responsible for + rendering the throwable. + +

The {@link SimpleLayout}, {@link TTCCLayout}, {@link + PatternLayout} all return true. The {@link + org.apache.log4j.xml.XMLLayout} returns false. + + @since 0.8.4 */ + abstract + public + boolean ignoresThrowable(); + } diff --git a/src/main/java/org/apache/log4j/Level.java b/src/main/java/org/apache/log4j/Level.java index 8c6d7b841d..3f713038a5 100644 --- a/src/main/java/org/apache/log4j/Level.java +++ b/src/main/java/org/apache/log4j/Level.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,6 +17,7 @@ // Contributors: Kitching Simon // Nicholas Wolff + package org.apache.log4j; import java.io.IOException; import java.io.ObjectInputStream; @@ -23,268 +25,231 @@ import java.io.ObjectStreamException; import java.io.Serializable; - /** - Defines the minimum set of levels recognized by the system, that is - OFF, FATAL, ERROR, - WARN, INFO, DEBUG, - TRACE, and ALL. - -

The Level class may be subclassed to define a larger - level set. - - @author Ceki Gülcü - @author Yoav Shapira - @author Curt Arnold + * Defines the minimum set of levels recognized by the system, that is OFF, FATAL, ERROR, + * WARN, INFO, DEBUG and ALL. + * + *

+ * The Level class may be subclassed to define a larger level set. + *

+ * + * @author Ceki Gülcü */ public class Level extends Priority implements Serializable { - /** - * TRACE level integer value. - * @since 1.2.12 - */ - public static final int TRACE_INT = 5000; - + private static final String ALL_NAME = "ALL"; - /** - * The OFF has the highest possible rank and is - * intended to turn off logging. - */ - public static final Level OFF = new Level(OFF_INT, "OFF", 0); + private static final String TRACE_NAME = "TRACE"; - /** - * The FATAL level designates very severe error - * events that will presumably lead the application to abort. - */ - public static final Level FATAL = new Level(FATAL_INT, "FATAL", 0); + private static final String DEBUG_NAME = "DEBUG"; - /** - * The ERROR level designates error events that - * might still allow the application to continue running. - */ - public static final Level ERROR = new Level(ERROR_INT, "ERROR", 3); + private static final String INFO_NAME = "INFO"; - /** - * The WARN level designates potentially harmful situations. - */ - public static final Level WARN = new Level(WARN_INT, "WARN", 4); + private static final String WARN_NAME = "WARN"; - /** - * The INFO level designates informational messages - * that highlight the progress of the application at coarse-grained - * level. - */ - public static final Level INFO = new Level(INFO_INT, "INFO", 6); + private static final String ERROR_NAME = "ERROR"; - /** - * The DEBUG Level designates fine-grained - * informational events that are most useful to debug an - * application. - */ - public static final Level DEBUG = new Level(DEBUG_INT, "DEBUG", 7); + private static final String FATAL_NAME = "FATAL"; - /** - * The TRACE Level designates finer-grained - * informational events than the DEBUGALL has the lowest possible rank and is intended to - * turn on all logging. - */ - public static final Level ALL = new Level(ALL_INT, "ALL", 7); + /** + * TRACE level integer value. + * + * @since 1.2.12 + */ + public static final int TRACE_INT = 5000; + /** + * The OFF has the highest possible rank and is intended to turn off logging. + */ + final static public Level OFF = new Level(OFF_INT, OFF_NAME, 0); - /** - * Serialization version id. - */ - static final long serialVersionUID = 3491141966387921974L; + /** + * The FATAL level designates very severe error events that will presumably lead the application to abort. + */ + final static public Level FATAL = new Level(FATAL_INT, FATAL_NAME, 0); + /** + * The ERROR level designates error events that might still allow the application to continue running. + */ + final static public Level ERROR = new Level(ERROR_INT, ERROR_NAME, 3); - /** - * Instantiate a level object. - * - * @param level The integer level value - * @param levelStr The level name - * @param syslogEquivalent The UNIX SystLog level equivalent - */ - protected Level(int level, String levelStr, int syslogEquivalent) { - super(level, levelStr, syslogEquivalent); - } + /** + * The WARN level designates potentially harmful situations. + */ + final static public Level WARN = new Level(WARN_INT, WARN_NAME, 4); - /** - * Convert the string passed as argument to a level. If the - * conversion fails, then this method returns {@link #DEBUG}. - * - * @param sArg The level name - * @return The matching Level object - */ - public static Level toLevel(String sArg) { - return toLevel(sArg, Level.DEBUG); - } - - /** - * Convert an integer passed as argument to a level. If the - * conversion fails, then this method returns {@link #DEBUG}. - * - * @param val The level integer value - * @return The matching Level object - */ - public static Level toLevel(int val) { - return toLevel(val, Level.DEBUG); - } - - /** - * Two Levels (formerly Priorities) are equal if their level - * integer value fields are equal. If the argument is not - * a Level, this method returns False. - * - * @param o The other Level - * @return boolean True if equals - * @since 1.2 - */ - public boolean equals(Object o) { - if (o instanceof Level) { - Level r = (Level) o; - - return (this.level == r.level); - } else { - return false; - } - } + /** + * The INFO level designates informational messages that highlight the progress of the application at coarse-grained level. + */ + final static public Level INFO = new Level(INFO_INT, INFO_NAME, 6); - /** - * The hashCode of a Level (i.e. Priority) is its level field. - * - * @return The integer level value - */ - public int hashCode() { - return level; - } + /** + * The DEBUG Level designates fine-grained informational events that are most useful to debug an application. + */ + final static public Level DEBUG = new Level(DEBUG_INT, DEBUG_NAME, 7); + /** + * The TRACE Level designates finer-grained informational events than the DEBUGALL
has the lowest possible rank and is intended to turn on all logging. + */ + final static public Level ALL = new Level(ALL_INT, ALL_NAME, 7); + /** + * Serialization version id. + */ + static final long serialVersionUID = 3491141966387921974L; - /** - * Convert an integer passed as argument to a level. If the - * conversion fails, then this method returns the specified default. - * - * @param val The integer value - * @param defaultLevel The Level to return if no match is found - * @return The matching Level - */ - public static Level toLevel(int val, Level defaultLevel) { - switch (val) { - case ALL_INT: - return ALL; - case TRACE_INT: - return TRACE; - case DEBUG_INT: - return DEBUG; - case INFO_INT: - return INFO; - case WARN_INT: - return WARN; - case ERROR_INT: - return ERROR; - case FATAL_INT: - return FATAL; - case OFF_INT: - return OFF; - default: - return defaultLevel; + /** + * Instantiate a Level object. + */ + protected Level(int level, String levelStr, int syslogEquivalent) { + super(level, levelStr, syslogEquivalent); } - } - /** - * Convert the string passed as argument to a level. If the - * conversion fails, then this method returns the - * defaultLevel. - * - * @param sArg The Level name - * @param defaultLevel Level to return if no match is found - * @return The matching Level - */ - public static Level toLevel(String sArg, Level defaultLevel) { - if (sArg == null) { - return defaultLevel; + /** + * Convert the string passed as argument to a level. If the conversion fails, then this method returns {@link #DEBUG}. + */ + public static Level toLevel(String sArg) { + return toLevel(sArg, Level.DEBUG); } - String s = sArg.toUpperCase(); - - if (s.equals("ALL")) { - return ALL; - } - - if (s.equals("TRACE")) { - return TRACE; - } - - if (s.equals("DEBUG")) { - return DEBUG; + /** + * Convert an integer passed as argument to a level. If the conversion fails, then this method returns {@link #DEBUG}. + */ + public static Level toLevel(int val) { + return toLevel(val, Level.DEBUG); } - if (s.equals("INFO")) { - return INFO; + /** + * Convert an integer passed as argument to a level. If the conversion fails, then this method returns the specified default. + */ + public static Level toLevel(int val, Level defaultLevel) { + switch (val) { + case ALL_INT: + return ALL; + case DEBUG_INT: + return Level.DEBUG; + case INFO_INT: + return Level.INFO; + case WARN_INT: + return Level.WARN; + case ERROR_INT: + return Level.ERROR; + case FATAL_INT: + return Level.FATAL; + case OFF_INT: + return OFF; + case TRACE_INT: + return Level.TRACE; + default: + return defaultLevel; + } } - if (s.equals("WARN")) { - return WARN; + /** + * Convert the string passed as argument to a level. If the conversion fails, then this method returns the value of + * defaultLevel. + */ + public static Level toLevel(String sArg, Level defaultLevel) { + if (sArg == null) { + return defaultLevel; + } + String s = sArg.toUpperCase(); + + if (s.equals(ALL_NAME)) { + return Level.ALL; + } + if (s.equals(DEBUG_NAME)) { + return Level.DEBUG; + } + if (s.equals(INFO_NAME)) { + return Level.INFO; + } + if (s.equals(WARN_NAME)) { + return Level.WARN; + } + if (s.equals(ERROR_NAME)) { + return Level.ERROR; + } + if (s.equals(FATAL_NAME)) { + return Level.FATAL; + } + if (s.equals(OFF_NAME)) { + return Level.OFF; + } + if (s.equals(TRACE_NAME)) { + return Level.TRACE; + } + // + // For Turkish i problem, see bug 40937 + // + if (s.equals("\u0130NFO")) { + return Level.INFO; + } + return defaultLevel; } - if (s.equals("ERROR")) { - return ERROR; + /** + * Custom deserialization of Level. + * + * @param s + * serialization stream. + * @throws IOException + * if IO exception. + * @throws ClassNotFoundException + * if class not found. + */ + private void readObject(final ObjectInputStream s) throws IOException, ClassNotFoundException { + s.defaultReadObject(); + level = s.readInt(); + syslogEquivalent = s.readInt(); + levelStr = s.readUTF(); + if (levelStr == null) { + levelStr = ""; + } } - if (s.equals("FATAL")) { - return FATAL; + /** + * Serialize level. + * + * @param s + * serialization stream. + * @throws IOException + * if exception during serialization. + */ + private void writeObject(final ObjectOutputStream s) throws IOException { + s.defaultWriteObject(); + s.writeInt(level); + s.writeInt(syslogEquivalent); + s.writeUTF(levelStr); } - if (s.equals("OFF")) { - return OFF; + /** + * Resolved deserialized level to one of the stock instances. May be overriden in classes derived from Level. + * + * @return resolved object. + * @throws ObjectStreamException + * if exception during resolution. + */ + private Object readResolve() throws ObjectStreamException { + // + // if the deserizalized object is exactly an instance of Level + // + if (getClass() == Level.class) { + return toLevel(level); + } + // + // extension of Level can't substitute stock item + // + return this; } - return defaultLevel; - } - - /** - * Custom deserialization of Level. - * @param s serialization stream. - * @throws IOException if IO exception. - * @throws ClassNotFoundException if class not found. - */ - private void readObject(final ObjectInputStream s) throws IOException, ClassNotFoundException { - s.defaultReadObject(); - level = s.readInt(); - syslogEquivalent = s.readInt(); - levelStr = s.readUTF(); - } - - /** - * Serialize level. - * @param s serialization stream. - * @throws IOException if exception during serialization. - */ - private void writeObject(final ObjectOutputStream s) throws IOException { - s.defaultWriteObject(); - s.writeInt(level); - s.writeInt(syslogEquivalent); - if (levelStr == null) { - s.writeUTF(""); - } else { - s.writeUTF(levelStr); - } - } - - /** - * Resolved deserialized level to one of the stock instances - * if possible. - * @return resolved object. - * @throws ObjectStreamException if exception during resolution. - */ - private Object readResolve() throws ObjectStreamException { - return toLevel(level, this); - } } diff --git a/src/main/java/org/apache/log4j/LogMF.java b/src/main/java/org/apache/log4j/LogMF.java new file mode 100755 index 0000000000..2df99fc150 --- /dev/null +++ b/src/main/java/org/apache/log4j/LogMF.java @@ -0,0 +1,1677 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j; + +import org.apache.log4j.spi.LoggingEvent; + +import java.text.DateFormat; +import java.text.MessageFormat; +import java.text.NumberFormat; +import java.util.Date; +import java.util.ResourceBundle; +import java.util.Locale; + + +/** + * This class provides parameterized logging services + * using the pattern syntax of java.text.MessageFormat. + * Message formatting is only performed when the + * request exceeds the threshold level of the logger. + * When the pattern only contains literal text and + * default conversion patterns (that is "{0}" and similar) + * a simple fast compatible formatter is used. + * If the pattern contains more complex conversion patterns, + * formatting will be delegated to java.text.MessageFormatter + * which can be substantially slower. + * + * @see org.apache.log4j.LogSF + * @since 1.2.16 + * + */ +public final class LogMF extends LogXF { + /** + * private constructor. + * + */ + private LogMF() { + } + + /** + * Number format. + */ + private static NumberFormat numberFormat = null; + /** + * Locale at time of last number format request. + */ + private static Locale numberLocale = null; + /** + * Date format. + */ + private static DateFormat dateFormat = null; + /** + * Locale at time of last date format request. + */ + private static Locale dateLocale = null; + + /** + * Format number. + * @param n number to format, may not be null. + * @return formatted value. + */ + private static synchronized String formatNumber(final Object n) { + Locale currentLocale = Locale.getDefault(); + if (currentLocale != numberLocale || numberFormat == null) { + numberLocale = currentLocale; + numberFormat = NumberFormat.getInstance(currentLocale); + } + return numberFormat.format(n); + } + + + /** + * Format date. + * @param d date, may not be null. + * @return formatted value. + */ + private static synchronized String formatDate(final Object d) { + Locale currentLocale = Locale.getDefault(); + if (currentLocale != dateLocale || dateFormat == null) { + dateLocale = currentLocale; + dateFormat = DateFormat.getDateTimeInstance( + DateFormat.SHORT, + DateFormat.SHORT, + currentLocale); + } + return dateFormat.format(d); + } + + /** + * Format a single parameter like a "{0}" formatting specifier. + * + * @param arg0 parameter, may be null. + * @return string representation of arg0. + */ + private static String formatObject(final Object arg0) { + if (arg0 instanceof String) { + return arg0.toString(); + } else if (arg0 instanceof Double || + arg0 instanceof Float) { + return formatNumber(arg0); + } else if (arg0 instanceof Date) { + return formatDate(arg0); + } + return String.valueOf(arg0); + } + + + /** + * Determines if pattern contains only {n} format elements + * and not apostrophes. + * + * @param pattern pattern, may not be null. + * @return true if pattern only contains {n} format elements. + */ + private static boolean isSimple(final String pattern) { + if (pattern.indexOf('\'') != -1) { + return false; + } + for(int pos = pattern.indexOf('{'); + pos != -1; + pos = pattern.indexOf('{', pos + 1)) { + if (pos + 2 >= pattern.length() || + pattern.charAt(pos+2) != '}' || + pattern.charAt(pos+1) < '0' || + pattern.charAt(pos+1) > '9') { + return false; + } + } + return true; + + } + + /** + * Formats arguments using MessageFormat. + * @param pattern pattern, may be malformed or null. + * @param arguments arguments, may be null or mismatched. + * @return Message string or null + */ + private static String format(final String pattern, + final Object[] arguments) { + if (pattern == null) { + return null; + } else if(isSimple(pattern)) { + String formatted[] = new String[10]; + int prev = 0; + String retval = ""; + int pos = pattern.indexOf('{'); + while(pos >= 0) { + if(pos + 2 < pattern.length() && + pattern.charAt(pos+2) == '}' && + pattern.charAt(pos+1) >= '0' && + pattern.charAt(pos+1) <= '9') { + int index = pattern.charAt(pos+1) - '0'; + retval += pattern.substring(prev, pos); + if (formatted[index] == null) { + if (arguments == null || index >= arguments.length) { + formatted[index] = pattern.substring(pos, pos+3); + } else { + formatted[index] = formatObject(arguments[index]); + } + } + retval += formatted[index]; + prev = pos + 3; + pos = pattern.indexOf('{', prev); + } else { + pos = pattern.indexOf('{', pos + 1); + } + } + retval += pattern.substring(prev); + return retval; + } + try { + return MessageFormat.format(pattern, arguments); + } catch (IllegalArgumentException ex) { + return pattern; + } + } + + /** + * Formats a single argument using MessageFormat. + * @param pattern pattern, may be malformed or null. + * @param arguments arguments, may be null or mismatched. + * @return Message string or null + */ + private static String format(final String pattern, + final Object arg0) { + if (pattern == null) { + return null; + } else if(isSimple(pattern)) { + String formatted = null; + int prev = 0; + String retval = ""; + int pos = pattern.indexOf('{'); + while(pos >= 0) { + if(pos + 2 < pattern.length() && + pattern.charAt(pos+2) == '}' && + pattern.charAt(pos+1) >= '0' && + pattern.charAt(pos+1) <= '9') { + int index = pattern.charAt(pos+1) - '0'; + retval += pattern.substring(prev, pos); + if (index != 0) { + retval += pattern.substring(pos, pos+3); + } else { + if (formatted == null) { + formatted = formatObject(arg0); + } + retval += formatted; + } + prev = pos + 3; + pos = pattern.indexOf('{', prev); + } else { + pos = pattern.indexOf('{', pos + 1); + } + } + retval += pattern.substring(prev); + return retval; + } + try { + return MessageFormat.format(pattern, new Object[] { arg0 }); + } catch (IllegalArgumentException ex) { + return pattern; + } + } + + + /** + * Formats arguments using MessageFormat using a pattern from + * a resource bundle. + * @param resourceBundleName name of resource bundle, may be null. + * @param key key for pattern in resource bundle, may be null. + * @param arguments arguments, may be null or mismatched. + * @return Message string or null + */ + private static String format( + final String resourceBundleName, + final String key, + final Object[] arguments) { + String pattern; + if (resourceBundleName != null) { + try { + ResourceBundle bundle = + ResourceBundle.getBundle(resourceBundleName); + pattern = bundle.getString(key); + } catch (Exception ex) { + pattern = key; + } + } else { + pattern = key; + } + return format(pattern, arguments); + } + + + /** + * Fully Qualified Class Name of this class. + */ + private static final String FQCN = LogMF.class.getName(); + + /** + * Equivalent of Logger.forcedLog. + * + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param msg message, may be null. + */ + private static void forcedLog(final Logger logger, + final Level level, + final String msg) { + logger.callAppenders(new LoggingEvent(FQCN, logger, level, msg, null)); + } + + /** + * Equivalent of Logger.forcedLog. + * + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param msg message, may be null. + * @param t throwable. + */ + private static void forcedLog(final Logger logger, + final Level level, + final String msg, + final Throwable t) { + logger.callAppenders(new LoggingEvent(FQCN, logger, level, msg, t)); + } + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be + * formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final Object[] arguments) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, arguments)); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final Object[] arguments) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, arguments)); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final Object[] arguments) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, arguments)); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final Object[] arguments) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, arguments)); + } + } + + /** + * Log a parameterized message at error level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void error(final Logger logger, final String pattern, + final Object[] arguments) { + if (logger.isEnabledFor(Level.ERROR)) { + forcedLog(logger, Level.ERROR, format(pattern, arguments)); + } + } + + /** + * Log a parameterized message at fatal level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void fatal(final Logger logger, final String pattern, + final Object[] arguments) { + if (logger.isEnabledFor(Level.FATAL)) { + forcedLog(logger, Level.FATAL, format(pattern, arguments)); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param t throwable, may be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be + * formatted and substituted. + */ + public static void trace(final Logger logger, + final Throwable t, + final String pattern, + final Object[] arguments) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, arguments), t); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param t throwable, may be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void debug(final Logger logger, + final Throwable t, + final String pattern, + final Object[] arguments) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, arguments), t); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param t throwable, may be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void info(final Logger logger, + final Throwable t, + final String pattern, + final Object[] arguments) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, arguments), t); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param t throwable, may be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void warn(final Logger logger, + final Throwable t, + final String pattern, + final Object[] arguments) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, arguments), t); + } + } + + /** + * Log a parameterized message at error level. + * @param logger logger, may not be null. + * @param t throwable, may be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void error(final Logger logger, + final Throwable t, + final String pattern, + final Object[] arguments) { + if (logger.isEnabledFor(Level.ERROR)) { + forcedLog(logger, Level.ERROR, format(pattern, arguments), t); + } + } + + /** + * Log a parameterized message at fatal level. + * @param logger logger, may not be null. + * @param t throwable, may be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void fatal(final Logger logger, + final Throwable t, + final String pattern, + final Object[] arguments) { + if (logger.isEnabledFor(Level.FATAL)) { + forcedLog(logger, Level.FATAL, format(pattern, arguments), t); + } + } + + + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final boolean argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final char argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final byte argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final short argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final int argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final long argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final float argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final double argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final Object argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, argument)); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final Object arg0, final Object arg1) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, + format(pattern, toArray(arg0, arg1))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final Object arg0, final Object arg1, final Object arg2) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, + format(pattern, toArray(arg0, arg1, arg2))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + * @param arg3 a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final Object arg0, final Object arg1, final Object arg2, + final Object arg3) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, + format(pattern, toArray(arg0, arg1, arg2, arg3))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final boolean argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final char argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final byte argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final short argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final int argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final long argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final float argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final double argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final Object argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, argument)); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final Object arg0, final Object arg1) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, + format(pattern, toArray(arg0, arg1))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final Object arg0, final Object arg1, final Object arg2) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, + format(pattern, toArray(arg0, arg1, arg2))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + * @param arg3 a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final Object arg0, final Object arg1, final Object arg2, + final Object arg3) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, + format(pattern, toArray(arg0, arg1, arg2, arg3))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final boolean argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final char argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final byte argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final short argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final int argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final long argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final float argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final double argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final Object argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, argument)); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final Object arg0, final Object arg1) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, toArray(arg0, arg1))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final Object arg0, final Object arg1, final Object arg2) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, + toArray(arg0, arg1, arg2))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + * @param arg3 a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final Object arg0, final Object arg1, final Object arg2, + final Object arg3) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, + toArray(arg0, arg1, arg2, arg3))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final boolean argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final char argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final byte argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final short argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final int argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final long argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final float argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final double argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final Object argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, argument)); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final Object arg0, final Object arg1) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, + format(pattern, toArray(arg0, arg1))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final Object arg0, final Object arg1, final Object arg2) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, + format(pattern, toArray(arg0, arg1, arg2))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + * @param arg3 a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final Object arg0, final Object arg1, final Object arg2, + final Object arg3) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, + toArray(arg0, arg1, arg2, arg3))); + } + } + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param parameters parameters to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final Object[] parameters) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, parameters)); + } + } + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param t throwable, may be null. + * @param pattern pattern, may be null. + * @param parameters parameters to the log message. + */ + public static void log(final Logger logger, + final Level level, + final Throwable t, + final String pattern, + final Object[] parameters) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, parameters), t); + } + } + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final Object param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(param1))); + } + } + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final boolean param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(valueOf(param1)))); + } + } + + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final byte param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(valueOf(param1)))); + } + } + + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final char param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(valueOf(param1)))); + } + } + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final short param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(valueOf(param1)))); + } + } + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final int param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(valueOf(param1)))); + } + } + + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final long param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(valueOf(param1)))); + } + } + + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final float param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(valueOf(param1)))); + } + } + + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final double param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(valueOf(param1)))); + } + } + + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final Object arg0, final Object arg1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(arg0, arg1))); + } + } + + /** + * Log a parameterized message at specifed level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final Object arg0, final Object arg1, final Object arg2) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(arg0, arg1, arg2))); + } + } + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param level level, may not be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + * @param arg3 a value to be formatted and substituted. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final Object arg0, final Object arg1, final Object arg2, + final Object arg3) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, format(pattern, + toArray(arg0, arg1, arg2, arg3))); + } + } + + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param parameters parameters to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final Object[] parameters) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, parameters)); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param t throwable, may be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param parameters parameters to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final Throwable t, + final String bundleName, + final String key, + final Object[] parameters) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, parameters), t); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final Object param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(param1))); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final boolean param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(valueOf(param1)))); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final char param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(valueOf(param1)))); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final byte param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(valueOf(param1)))); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final short param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(valueOf(param1)))); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final int param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(valueOf(param1)))); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final long param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(valueOf(param1)))); + } + } + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final float param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(valueOf(param1)))); + } + } + + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final double param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(valueOf(param1)))); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param0 Parameter to the log message. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final Object param0, + final Object param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(param0, param1))); + } + } + + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param0 Parameter to the log message. + * @param param1 Parameter to the log message. + * @param param2 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final Object param0, + final Object param1, + final Object param2) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(param0, param1, param2))); + } + } + + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param0 Parameter to the log message. + * @param param1 Parameter to the log message. + * @param param2 Parameter to the log message. + * @param param3 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final Object param0, + final Object param1, + final Object param2, + final Object param3) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, + toArray(param0, param1, param2, param3))); + } + } + +} diff --git a/src/main/java/org/apache/log4j/LogManager.java b/src/main/java/org/apache/log4j/LogManager.java index 0d15efd940..ef48a0fd4b 100644 --- a/src/main/java/org/apache/log4j/LogManager.java +++ b/src/main/java/org/apache/log4j/LogManager.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,29 +17,34 @@ package org.apache.log4j; -import org.apache.log4j.helpers.Constants; -import org.apache.log4j.helpers.IntializationUtil; -import org.apache.log4j.helpers.Loader; -import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.selector.ContextJNDISelector; -import org.apache.log4j.spi.DefaultRepositorySelector; -import org.apache.log4j.spi.LoggerFactory; 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.RootLogger; +import org.apache.log4j.spi.NOPLoggerRepository; +import org.apache.log4j.helpers.Loader; +import org.apache.log4j.helpers.OptionConverter; +import org.apache.log4j.helpers.LogLog; + +import java.net.URL; +import java.net.MalformedURLException; -import java.util.Enumeration; +import java.util.Enumeration; +import java.io.StringWriter; +import java.io.PrintWriter; /** - * Use the LogManager class to retreive {@link Logger} - * instances or to operate on the current {@link - * LoggerRepository}. When the LogManager class is loaded - * into memory the default initalzation procedure is inititated. The - * default intialization procedure is described in the short log4j manual. - * - * @author Ceki Gülcü */ + * Gets {@link Logger} instances and operates on the current {@link LoggerRepository}. + * + *

+ * When the LogManager class is loaded into memory the default initialization procedure runs. The default initialization + * procedure is described in the short log4j manual. + *

+ * + * @author Ceki Gülcü + */ public class LogManager { /** @@ -47,10 +53,6 @@ public class LogManager { * */ static public final String DEFAULT_CONFIGURATION_FILE = "log4j.properties"; - /** - * @deprecated This variable is for internal use only. It will - * become package protected in future versions. - * */ static final String DEFAULT_XML_CONFIGURATION_FILE = "log4j.xml"; /** @@ -72,229 +74,204 @@ public class LogManager { public static final String DEFAULT_INIT_OVERRIDE_KEY = "log4j.defaultInitOverride"; - /** - * Concurrency guard. - */ - private static Object guard = null; - /** - * The repository selector. - */ - private static RepositorySelector repositorySelector; + static private Object guard = null; + static private RepositorySelector repositorySelector; - /** - * The debug flag, false by default. - * True will cause debug printing to System.out. - * Modify via system property log4j.debug. - */ - private static boolean debug = false; + static { + // By default we use a DefaultRepositorySelector which always returns 'h'. + Hierarchy h = new Hierarchy(new RootLogger(Level.DEBUG)); + repositorySelector = new DefaultRepositorySelector(h); - /** - * The default LoggerRepository instance created by LogManager. This instance - * is provided for the convenience of the {@link RepositorySelector} instance. - * The selector, if it choses, may ignore this default repository. - */ - public static final LoggerRepository defaultLoggerRepository; - + /** Search for the properties file log4j.properties in the CLASSPATH. */ + String override =OptionConverter.getSystemProperty(DEFAULT_INIT_OVERRIDE_KEY, + null); - /** - * The following static initializer gets invoked immediately after a call to - * Logger.getLogger() is made. Here is a description of the static initializer: - * - * - Create defaultLoggerRepository, - * - Configure(defaultLoggerRepository) depending on system properties, - * during the configuration of defaultLoggerRepository a temporary repository - * selector is used. - */ - static { - // Check debug - String debugProp = System.getProperty("log4j.debug"); - if(Boolean.valueOf(debugProp).booleanValue()) { - debug = true; - } + // 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)) { - if(debug) { - System.out.println("**Start of LogManager static initializer"); - } + String configurationOptionStr = OptionConverter.getSystemProperty( + DEFAULT_CONFIGURATION_KEY, + null); - Hierarchy hierarchy = new Hierarchy(new RootLogger(Level.DEBUG)); - defaultLoggerRepository = hierarchy; - hierarchy.setName(Constants.DEFAULT_REPOSITORY_NAME); - - // temporary repository - repositorySelector = new DefaultRepositorySelector(defaultLoggerRepository); - - // Attempt to perform automatic configuration of the default repository - String configuratorClassName = - OptionConverter.getSystemProperty(Constants.CONFIGURATOR_CLASS_KEY, null); - String configurationOptionStr = - OptionConverter.getSystemProperty(Constants.DEFAULT_CONFIGURATION_KEY, null); - - if (configurationOptionStr == null) { - if (Loader.getResource(Constants.DEFAULT_XML_CONFIGURATION_FILE) != null) { - configurationOptionStr = Constants.DEFAULT_XML_CONFIGURATION_FILE; - } else if ( - Loader.getResource(Constants.DEFAULT_CONFIGURATION_FILE) != null) { - configurationOptionStr = Constants.DEFAULT_CONFIGURATION_FILE; - } - } - - if(debug) { - System.out.println("*** configurationOptionStr=" + configurationOptionStr); - } + String configuratorClassName = OptionConverter.getSystemProperty( + CONFIGURATOR_CLASS_KEY, + null); + + URL url = null; + + // 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); + } + } - IntializationUtil.initialConfiguration( - defaultLoggerRepository, configurationOptionStr, configuratorClassName); - - String repositorySelectorStr = - OptionConverter.getSystemProperty("log4j.repositorySelector", null); - - if (repositorySelectorStr == null) { - // NOTHING TO DO, the default repository has been configured already - } else if (repositorySelectorStr.equalsIgnoreCase("JNDI")) { - if(debug) { - System.out.println("*** Will use ContextJNDISelector **"); - } - - repositorySelector = new ContextJNDISelector(); - guard = new Object(); - } else { - Object r = - OptionConverter.instantiateByClassName( - repositorySelectorStr, RepositorySelector.class, null); - - if (r instanceof RepositorySelector) { - if(debug) { - System.out.println( - "*** Using [" + repositorySelectorStr - + "] instance as repository selector."); - } - repositorySelector = (RepositorySelector) r; - guard = new Object(); - } else { - if(debug) { - System.out.println( - "*** Could not insantiate [" + repositorySelectorStr - + "] as repository selector."); - System.out.println("*** Using default repository selector"); - } - - repositorySelector = new DefaultRepositorySelector(defaultLoggerRepository); - } + // 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."); + try { + OptionConverter.selectAndConfigure(url, configuratorClassName, + LogManager.getLoggerRepository()); + } catch (NoClassDefFoundError e) { + LogLog.warn("Error during default initialization", e); } + } else { + LogLog.debug("Could not find resource: ["+configurationOptionStr+"]."); + } + } else { + LogLog.debug("Default initialization of overridden by " + + DEFAULT_INIT_OVERRIDE_KEY + "property."); + } + } - if(debug) { - System.out.println("** End of LogManager static initializer"); - } + /** + Sets LoggerFactory but only if the correct + guard is passed as parameter. + +

Initally the guard is null. If the guard is + null, then invoking this method sets the logger + factory and the guard. Following invocations will throw a {@link + IllegalArgumentException}, unless the previously set + guard is passed as the second parameter. + +

This allows a high-level component to set the {@link + RepositorySelector} used by the LogManager. + +

For example, when tomcat starts it will be able to install its + own repository selector. However, if and when Tomcat is embedded + within JBoss, then JBoss will install its own repository selector + and Tomcat will use the repository selector set by its container, + JBoss. */ + static + public + void setRepositorySelector(RepositorySelector selector, Object guard) + throws IllegalArgumentException { + if((LogManager.guard != null) && (LogManager.guard != guard)) { + throw new IllegalArgumentException( + "Attempted to reset the LoggerFactory without possessing the guard."); } - /** - Sets RepositorySelector but only if the correct - guard is passed as parameter. - -

Initally the guard is null, unless the JVM is started with the - log4j.repositorySelector system property - (-Dlog4j.repositorySelector=[JNDI | ]). - If the guard is - null, then invoking this method sets the logger - repository and the guard. Following invocations will throw a {@link - IllegalArgumentException}, unless the previously set - guard is passed as the second parameter. - -

This allows a high-level component to set the {@link - RepositorySelector} used by the LogManager. - -

For example, when tomcat starts it will be able to install its - own repository selector. However, if and when Tomcat is embedded - within JBoss, then JBoss will install its own repository selector - and Tomcat will use the repository selector set by its container, - JBoss. - - @param selector new selector, cannot be null - @param guard new guard value, or existing guard, or null - @throws IllegalArgumentException if a non-null guard is not the same as the old - @throws IllegalArgumentException if the selector is null - @throws IllegalArgumentException if {@link RepositorySelector#getLoggerRepository()} returns null - */ - public static void setRepositorySelector(RepositorySelector selector, Object guard) { - if ((LogManager.guard != null) && (LogManager.guard != guard)) { - throw new IllegalArgumentException("Attempted to reset the LoggerFactory without possessing the guard."); - } - if (selector == null) { - throw new IllegalArgumentException("RepositorySelector must be non-null."); - } - if (selector.getLoggerRepository() == null) { - String s = "RepositorySelector.getLoggerRepository() must return non-null."; - throw new IllegalArgumentException(s); - } - - LogManager.guard = guard; - LogManager.repositorySelector = selector; + if(selector == null) { + throw new IllegalArgumentException("RepositorySelector must be non-null."); } - - - /** - * Return the repository selector currently in use. - * - * @since 1.3 - * @return {@link RepositorySelector} currently in use. - */ - public static RepositorySelector getRepositorySelector() { - return LogManager.repositorySelector; - } - + + LogManager.guard = guard; + LogManager.repositorySelector = selector; + } + + /** - * Returns the logger repository currently in use. + * This method tests if called from a method that + * is known to result in class members being abnormally + * set to null but is assumed to be harmless since the + * all classes are in the process of being unloaded. + * + * @param ex exception used to determine calling stack. + * @return true if calling stack is recognized as likely safe. */ - public static LoggerRepository getLoggerRepository() { - return repositorySelector.getLoggerRepository(); - } - - /** - Retrieve the appropriate root logger. - */ - public static Logger getRootLogger() { - // Delegate the actual manufacturing of the logger to the logger repository. - return repositorySelector.getLoggerRepository().getRootLogger(); - } - - /** - Retrieve the appropriate {@link Logger} instance. - */ - public static Logger getLogger(String name) { - // Delegate the actual manufacturing of the logger to the logger repository. - return repositorySelector.getLoggerRepository().getLogger(name); - } - - /** - Retrieve the appropriate {@link Logger} instance. - */ - public static Logger getLogger(Class clazz) { - // Delegate the actual manufacturing of the logger to the logger repository. - return repositorySelector.getLoggerRepository().getLogger(clazz.getName()); - } - - /** - Retrieve the appropriate {@link Logger} instance. - */ - public static Logger getLogger(String name, LoggerFactory factory) { - // Delegate the actual manufacturing of the logger to the logger repository. - return repositorySelector.getLoggerRepository().getLogger(name, factory); - } - - public static Logger exists(String name) { - return repositorySelector.getLoggerRepository().exists(name); - } - - public static Enumeration getCurrentLoggers() { - return repositorySelector.getLoggerRepository().getCurrentLoggers(); - } - - public static void shutdown() { - repositorySelector.getLoggerRepository().shutdown(); - } - - public static void resetConfiguration() { - repositorySelector.getLoggerRepository().resetConfiguration(); + private static boolean isLikelySafeScenario(final Exception ex) { + StringWriter stringWriter = new StringWriter(); + ex.printStackTrace(new PrintWriter(stringWriter)); + String msg = stringWriter.toString(); + return msg.indexOf("org.apache.catalina.loader.WebappClassLoader.stop") != -1; + } + + static + public + LoggerRepository getLoggerRepository() { + if (repositorySelector == null) { + repositorySelector = new DefaultRepositorySelector(new NOPLoggerRepository()); + guard = null; + Exception ex = new IllegalStateException("Class invariant violation"); + String msg = + "log4j called after unloading, see http://logging.apache.org/log4j/1.2/faq.html#unload."; + if (isLikelySafeScenario(ex)) { + LogLog.debug(msg, ex); + } else { + LogLog.error(msg, ex); + } } + return repositorySelector.getLoggerRepository(); + } + + /** + Retrieve the appropriate root logger. + */ + public + static + Logger getRootLogger() { + // Delegate the actual manufacturing of the logger to the logger repository. + return getLoggerRepository().getRootLogger(); + } + + /** + Retrieve the appropriate {@link Logger} instance. + */ + public + static + Logger getLogger(final String name) { + // Delegate the actual manufacturing of the logger to the logger repository. + return getLoggerRepository().getLogger(name); + } + + /** + Retrieve the appropriate {@link Logger} instance. + */ + public + static + Logger getLogger(final Class clazz) { + // Delegate the actual manufacturing of the logger to the logger repository. + return getLoggerRepository().getLogger(clazz.getName()); + } + + + /** + Retrieve the appropriate {@link Logger} instance. + */ + public + static + Logger getLogger(final String name, final LoggerFactory factory) { + // Delegate the actual manufacturing of the logger to the logger repository. + return getLoggerRepository().getLogger(name, factory); + } + + public + static + Logger exists(final String name) { + return getLoggerRepository().exists(name); + } + + public + static + Enumeration getCurrentLoggers() { + return getLoggerRepository().getCurrentLoggers(); + } + + public + static + void shutdown() { + getLoggerRepository().shutdown(); + } + + public + static + void resetConfiguration() { + getLoggerRepository().resetConfiguration(); + } } + diff --git a/src/main/java/org/apache/log4j/LogSF.java b/src/main/java/org/apache/log4j/LogSF.java new file mode 100755 index 0000000000..8302e205e7 --- /dev/null +++ b/src/main/java/org/apache/log4j/LogSF.java @@ -0,0 +1,1541 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j; + +import org.apache.log4j.spi.LoggingEvent; + +import java.util.ResourceBundle; + + +/** + * This class provides parameterized logging services + * using the SLF4J pattern syntax. + *

+ * Message formatting is only performed when the + * request exceeds the threshold level of the logger. + * + * @since 1.2.16 + * + */ +public final class LogSF extends LogXF { + /** + * private constructor. + * + */ + private LogSF() { + } + + + + + /** + * Formats arguments using SLF4J-like formatter. + * @param pattern pattern, may be malformed. + * @param arguments arguments. + * @return Message string + */ + private static String format(final String pattern, + final Object[] arguments) { + if (pattern != null) { + String retval = ""; + int count = 0; + int prev = 0; + int pos = pattern.indexOf("{"); + while(pos >= 0) { + if (pos == 0 || pattern.charAt(pos-1) != '\\') { + retval += pattern.substring(prev, pos); + if (pos + 1 < pattern.length() && pattern.charAt(pos+1) == '}') { + if(arguments != null && count < arguments.length) { + retval += arguments[count++]; + } else { + retval += "{}"; + } + prev = pos + 2; + } else { + retval += "{"; + prev = pos + 1; + } + } else { + retval += pattern.substring(prev, pos - 1) + "{"; + prev = pos + 1; + } + pos = pattern.indexOf("{", prev); + } + return retval + pattern.substring(prev); + } + return null; + } + + /** + * Formats arguments using MessageFormat. + * @param pattern pattern, may be malformed. + * @param arg0 argument, may be null or mismatched. + * @return Message string + */ + private static String format(final String pattern, final Object arg0) { + if (pattern != null) { + // + // if there is an escaped brace, delegate to multi-param formatter + if (pattern.indexOf("\\{") >= 0) { + return format(pattern, new Object[] { arg0 }); + } + int pos = pattern.indexOf("{}"); + if (pos >= 0) { + return pattern.substring(0, pos) + arg0 + pattern.substring(pos+2); + } + } + return pattern; + } + + /** + * Formats arguments using MessageFormat using a pattern from + * a resource bundle. + * @param resourceBundleName name of resource bundle, may be null. + * @param key key for pattern in resource bundle, may be null. + * @param arguments arguments, may be null or mismatched. + * @return Message string or null + */ + private static String format( + final String resourceBundleName, + final String key, + final Object[] arguments) { + String pattern; + if (resourceBundleName != null) { + try { + ResourceBundle bundle = + ResourceBundle.getBundle(resourceBundleName); + pattern = bundle.getString(key); + } catch (Exception ex) { + pattern = key; + } + } else { + pattern = key; + } + return format(pattern, arguments); + } + + + /** + * Fully Qualified Class Name of this class. + */ + private static final String FQCN = LogSF.class.getName(); + + /** + * Equivalent of Logger.forcedLog. + * + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param msg message, may be null. + */ + private static void forcedLog(final Logger logger, + final Level level, + final String msg) { + logger.callAppenders(new LoggingEvent(FQCN, logger, level, msg, null)); + } + + /** + * Equivalent of Logger.forcedLog. + * + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param msg message, may be null. + * @param t throwable. + */ + private static void forcedLog(final Logger logger, + final Level level, + final String msg, + final Throwable t) { + logger.callAppenders(new LoggingEvent(FQCN, logger, level, msg, t)); + } + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be + * formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final Object[] arguments) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, arguments)); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final Object[] arguments) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, arguments)); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final Object[] arguments) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, arguments)); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final Object[] arguments) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, arguments)); + } + } + + /** + * Log a parameterized message at error level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void error(final Logger logger, final String pattern, + final Object[] arguments) { + if (logger.isEnabledFor(Level.ERROR)) { + forcedLog(logger, Level.ERROR, format(pattern, arguments)); + } + } + + /** + * Log a parameterized message at fatal level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void fatal(final Logger logger, final String pattern, + final Object[] arguments) { + if (logger.isEnabledFor(Level.FATAL)) { + forcedLog(logger, Level.FATAL, format(pattern, arguments)); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param t throwable, may be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be + * formatted and substituted. + */ + public static void trace(final Logger logger, + final Throwable t, + final String pattern, + final Object[] arguments) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, arguments), t); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param t throwable, may be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void debug(final Logger logger, + final Throwable t, + final String pattern, + final Object[] arguments) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, arguments), t); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param t throwable, may be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void info(final Logger logger, + final Throwable t, + final String pattern, + final Object[] arguments) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, arguments), t); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param t throwable, may be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void warn(final Logger logger, + final Throwable t, + final String pattern, + final Object[] arguments) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, arguments), t); + } + } + + /** + * Log a parameterized message at error level. + * @param logger logger, may not be null. + * @param t throwable, may be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void error(final Logger logger, + final Throwable t, + final String pattern, + final Object[] arguments) { + if (logger.isEnabledFor(Level.ERROR)) { + forcedLog(logger, Level.ERROR, format(pattern, arguments), t); + } + } + + /** + * Log a parameterized message at fatal level. + * @param logger logger, may not be null. + * @param t throwable, may be null. + * @param pattern pattern, may be null. + * @param arguments an array of arguments to be formatted and substituted. + */ + public static void fatal(final Logger logger, + final Throwable t, + final String pattern, + final Object[] arguments) { + if (logger.isEnabledFor(Level.FATAL)) { + forcedLog(logger, Level.FATAL, format(pattern, arguments), t); + } + } + + + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final boolean argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final char argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final byte argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final short argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final int argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final long argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final float argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final double argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final Object argument) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, format(pattern, argument)); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final Object arg0, final Object arg1) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, + format(pattern, toArray(arg0, arg1))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final Object arg0, final Object arg1, final Object arg2) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, + format(pattern, toArray(arg0, arg1, arg2))); + } + } + + /** + * Log a parameterized message at trace level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + * @param arg3 a value to be formatted and substituted. + */ + public static void trace(final Logger logger, final String pattern, + final Object arg0, final Object arg1, final Object arg2, + final Object arg3) { + if (logger.isEnabledFor(TRACE)) { + forcedLog(logger, TRACE, + format(pattern, toArray(arg0, arg1, arg2, arg3))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final boolean argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final char argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final byte argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final short argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final int argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final long argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final float argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final double argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final Object argument) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, format(pattern, argument)); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final Object arg0, final Object arg1) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, + format(pattern, toArray(arg0, arg1))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final Object arg0, final Object arg1, final Object arg2) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, + format(pattern, toArray(arg0, arg1, arg2))); + } + } + + /** + * Log a parameterized message at debug level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + * @param arg3 a value to be formatted and substituted. + */ + public static void debug(final Logger logger, final String pattern, + final Object arg0, final Object arg1, final Object arg2, + final Object arg3) { + if (logger.isDebugEnabled()) { + forcedLog(logger, Level.DEBUG, + format(pattern, toArray(arg0, arg1, arg2, arg3))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final boolean argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final char argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final byte argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final short argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final int argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final long argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final float argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final double argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final Object argument) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, argument)); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final Object arg0, final Object arg1) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, toArray(arg0, arg1))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final Object arg0, final Object arg1, final Object arg2) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, + toArray(arg0, arg1, arg2))); + } + } + + /** + * Log a parameterized message at info level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + * @param arg3 a value to be formatted and substituted. + */ + public static void info(final Logger logger, final String pattern, + final Object arg0, final Object arg1, final Object arg2, + final Object arg3) { + if (logger.isInfoEnabled()) { + forcedLog(logger, Level.INFO, format(pattern, + toArray(arg0, arg1, arg2, arg3))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final boolean argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final char argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final byte argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final short argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final int argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final long argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final float argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final double argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, valueOf(argument))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param argument a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final Object argument) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, argument)); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final Object arg0, final Object arg1) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, + format(pattern, toArray(arg0, arg1))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final Object arg0, final Object arg1, final Object arg2) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, + format(pattern, toArray(arg0, arg1, arg2))); + } + } + + /** + * Log a parameterized message at warn level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + * @param arg3 a value to be formatted and substituted. + */ + public static void warn(final Logger logger, final String pattern, + final Object arg0, final Object arg1, final Object arg2, + final Object arg3) { + if (logger.isEnabledFor(Level.WARN)) { + forcedLog(logger, Level.WARN, format(pattern, + toArray(arg0, arg1, arg2, arg3))); + } + } + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param parameters parameters to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final Object[] parameters) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, parameters)); + } + } + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param t throwable, may be null. + * @param pattern pattern, may be null. + * @param parameters parameters to the log message. + */ + public static void log(final Logger logger, + final Level level, + final Throwable t, + final String pattern, + final Object[] parameters) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, parameters), t); + } + } + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final Object param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(param1))); + } + } + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final boolean param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(valueOf(param1)))); + } + } + + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final byte param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(valueOf(param1)))); + } + } + + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final char param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(valueOf(param1)))); + } + } + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final short param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(valueOf(param1)))); + } + } + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final int param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(valueOf(param1)))); + } + } + + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final long param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(valueOf(param1)))); + } + } + + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final float param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(valueOf(param1)))); + } + } + + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param param1 parameter to the log message. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final double param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(valueOf(param1)))); + } + } + + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final Object arg0, final Object arg1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(arg0, arg1))); + } + } + + /** + * Log a parameterized message at specifed level. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param pattern pattern, may be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final Object arg0, final Object arg1, final Object arg2) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(pattern, toArray(arg0, arg1, arg2))); + } + } + + /** + * Log a parameterized message at specified level. + * @param logger logger, may not be null. + * @param pattern pattern, may be null. + * @param level level, may not be null. + * @param arg0 a value to be formatted and substituted. + * @param arg1 a value to be formatted and substituted. + * @param arg2 a value to be formatted and substituted. + * @param arg3 a value to be formatted and substituted. + */ + public static void log(final Logger logger, + final Level level, + final String pattern, + final Object arg0, final Object arg1, final Object arg2, + final Object arg3) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, format(pattern, + toArray(arg0, arg1, arg2, arg3))); + } + } + + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param parameters parameters to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final Object[] parameters) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, parameters)); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param t throwable, may be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param parameters parameters to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final Throwable t, + final String bundleName, + final String key, + final Object[] parameters) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, parameters), t); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final Object param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(param1))); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final boolean param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(valueOf(param1)))); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final char param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(valueOf(param1)))); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final byte param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(valueOf(param1)))); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final short param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(valueOf(param1)))); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final int param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(valueOf(param1)))); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final long param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(valueOf(param1)))); + } + } + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final float param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(valueOf(param1)))); + } + } + + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final double param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(valueOf(param1)))); + } + } + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param0 Parameter to the log message. + * @param param1 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final Object param0, + final Object param1) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(param0, param1))); + } + } + + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param0 Parameter to the log message. + * @param param1 Parameter to the log message. + * @param param2 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final Object param0, + final Object param1, + final Object param2) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, toArray(param0, param1, param2))); + } + } + + + /** + * Log a parameterized message using a pattern from a resource bundle. + * @param logger logger, may not be null. + * @param level level, may not be null. + * @param bundleName resource bundle name, may be null. + * @param key key, may be null. + * @param param0 Parameter to the log message. + * @param param1 Parameter to the log message. + * @param param2 Parameter to the log message. + * @param param3 Parameter to the log message. + */ + public static void logrb(final Logger logger, + final Level level, + final String bundleName, + final String key, + final Object param0, + final Object param1, + final Object param2, + final Object param3) { + if (logger.isEnabledFor(level)) { + forcedLog(logger, level, + format(bundleName, key, + toArray(param0, param1, param2, param3))); + } + } +} diff --git a/src/main/java/org/apache/log4j/LogXF.java b/src/main/java/org/apache/log4j/LogXF.java new file mode 100644 index 0000000000..de2b94b7e4 --- /dev/null +++ b/src/main/java/org/apache/log4j/LogXF.java @@ -0,0 +1,371 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j; + +import org.apache.log4j.spi.LoggingEvent; + +/** + * This is a base class for LogMF and LogSF parameterized logging classes. + * + * + * @see org.apache.log4j.LogMF + * @see org.apache.log4j.LogSF + * @since 1.2.16 + */ +public abstract class LogXF { + /** + * Trace level. + */ + protected static final Level TRACE = new Level(5000, "TRACE", 7); + /** + * Fully Qualified Class Name of this class. + */ + private static final String FQCN = LogXF.class.getName(); + + protected LogXF() { + } + + /** + * Returns a Boolean instance representing the specified boolean. + * Boolean.valueOf was added in JDK 1.4. + * + * @param b a boolean value. + * @return a Boolean instance representing b. + */ + protected static Boolean valueOf(final boolean b) { + if (b) { + return Boolean.TRUE; + } + return Boolean.FALSE; + } + + /** + * Returns a Character instance representing the specified char. + * Character.valueOf was added in JDK 1.5. + * + * @param c a character value. + * @return a Character instance representing c. + */ + protected static Character valueOf(final char c) { + return new Character(c); + } + + /** + * Returns a Byte instance representing the specified byte. + * Byte.valueOf was added in JDK 1.5. + * + * @param b a byte value. + * @return a Byte instance representing b. + */ + protected static Byte valueOf(final byte b) { + return new Byte(b); + } + + /** + * Returns a Short instance representing the specified short. + * Short.valueOf was added in JDK 1.5. + * + * @param b a short value. + * @return a Byte instance representing b. + */ + protected static Short valueOf(final short b) { + return new Short(b); + } + + /** + * Returns an Integer instance representing the specified int. + * Integer.valueOf was added in JDK 1.5. + * + * @param b an int value. + * @return an Integer instance representing b. + */ + protected static Integer valueOf(final int b) { + return new Integer(b); + } + + /** + * Returns a Long instance representing the specified long. + * Long.valueOf was added in JDK 1.5. + * + * @param b a long value. + * @return a Long instance representing b. + */ + protected static Long valueOf(final long b) { + return new Long(b); + } + + /** + * Returns a Float instance representing the specified float. + * Float.valueOf was added in JDK 1.5. + * + * @param b a float value. + * @return a Float instance representing b. + */ + protected static Float valueOf(final float b) { + return new Float(b); + } + + /** + * Returns a Double instance representing the specified double. + * Double.valueOf was added in JDK 1.5. + * + * @param b a double value. + * @return a Byte instance representing b. + */ + protected static Double valueOf(final double b) { + return new Double(b); + } + + /** + * Create new array. + * + * @param param1 parameter 1. + * @return new array. + */ + protected static Object[] toArray(final Object param1) { + return new Object[]{ + param1 + }; + } + + /** + * Create new array. + * + * @param param1 parameter 1. + * @param param2 parameter 2. + * @return new array. + */ + protected static Object[] toArray(final Object param1, + final Object param2) { + return new Object[]{ + param1, param2 + }; + } + + /** + * Create new array. + * + * @param param1 parameter 1. + * @param param2 parameter 2. + * @param param3 parameter 3. + * @return new array. + */ + protected static Object[] toArray(final Object param1, + final Object param2, + final Object param3) { + return new Object[]{ + param1, param2, param3 + }; + } + + /** + * Create new array. + * + * @param param1 parameter 1. + * @param param2 parameter 2. + * @param param3 parameter 3. + * @param param4 parameter 4. + * @return new array. + */ + protected static Object[] toArray(final Object param1, + final Object param2, + final Object param3, + final Object param4) { + return new Object[]{ + param1, param2, param3, param4 + }; + } + + /** + * Log an entering message at DEBUG level. + * + * @param logger logger, may not be null. + * @param sourceClass source class, may be null. + * @param sourceMethod method, may be null. + */ + public static void entering(final Logger logger, + final String sourceClass, + final String sourceMethod) { + if (logger.isDebugEnabled()) { + logger.callAppenders(new LoggingEvent(FQCN, logger, Level.DEBUG, + sourceClass + "." + sourceMethod + " ENTRY", null)); + } + } + + /** + * Log an entering message with a parameter at DEBUG level. + * + * @param logger logger, may not be null. + * @param sourceClass source class, may be null. + * @param sourceMethod method, may be null. + * @param param parameter, may be null. + */ + public static void entering(final Logger logger, + final String sourceClass, + final String sourceMethod, + final String param) { + if (logger.isDebugEnabled()) { + String msg = sourceClass + "." + sourceMethod + " ENTRY " + param; + logger.callAppenders(new LoggingEvent(FQCN, logger, Level.DEBUG, + msg, null)); + } + } + + /** + * Log an entering message with a parameter at DEBUG level. + * + * @param logger logger, may not be null. + * @param sourceClass source class, may be null. + * @param sourceMethod method, may be null. + * @param param parameter, may be null. + */ + public static void entering(final Logger logger, + final String sourceClass, + final String sourceMethod, + final Object param) { + if (logger.isDebugEnabled()) { + String msg = sourceClass + "." + sourceMethod + " ENTRY "; + if (param == null) { + msg += "null"; + } else { + try { + msg += param; + } catch(Throwable ex) { + msg += "?"; + } + } + logger.callAppenders(new LoggingEvent(FQCN, logger, Level.DEBUG, + msg, null)); + } + } + + /** + * Log an entering message with an array of parameters at DEBUG level. + * + * @param logger logger, may not be null. + * @param sourceClass source class, may be null. + * @param sourceMethod method, may be null. + * @param params parameters, may be null. + */ + public static void entering(final Logger logger, + final String sourceClass, + final String sourceMethod, + final Object[] params) { + if (logger.isDebugEnabled()) { + String msg = sourceClass + "." + sourceMethod + " ENTRY "; + if (params != null && params.length > 0) { + String delim = "{"; + for (int i = 0; i < params.length; i++) { + try { + msg += delim + params[i]; + } catch(Throwable ex) { + msg += delim + "?"; + } + delim = ","; + } + msg += "}"; + } else { + msg += "{}"; + } + logger.callAppenders(new LoggingEvent(FQCN, logger, Level.DEBUG, + msg, null)); + } + } + + /** + * Log an exiting message at DEBUG level. + * + * @param logger logger, may not be null. + * @param sourceClass source class, may be null. + * @param sourceMethod method, may be null. + */ + public static void exiting(final Logger logger, + final String sourceClass, + final String sourceMethod) { + if (logger.isDebugEnabled()) { + logger.callAppenders(new LoggingEvent(FQCN, logger, Level.DEBUG, + sourceClass + "." + sourceMethod + " RETURN", null)); + } + } + + /** + * Log an exiting message with result at DEBUG level. + * + * @param logger logger, may not be null. + * @param sourceClass source class, may be null. + * @param sourceMethod method, may be null. + * @param result result, may be null. + */ + public static void exiting( + final Logger logger, + final String sourceClass, + final String sourceMethod, + final String result) { + if (logger.isDebugEnabled()) { + logger.callAppenders(new LoggingEvent(FQCN, logger, Level.DEBUG, + sourceClass + "." + sourceMethod + " RETURN " + result, null)); + } + } + + /** + * Log an exiting message with result at DEBUG level. + * + * @param logger logger, may not be null. + * @param sourceClass source class, may be null. + * @param sourceMethod method, may be null. + * @param result result, may be null. + */ + public static void exiting( + final Logger logger, + final String sourceClass, + final String sourceMethod, + final Object result) { + if (logger.isDebugEnabled()) { + String msg = sourceClass + "." + sourceMethod + " RETURN "; + if (result == null) { + msg += "null"; + } else { + try { + msg += result; + } catch(Throwable ex) { + msg += "?"; + } + } + logger.callAppenders(new LoggingEvent(FQCN, logger, Level.DEBUG, + msg, null)); + } + } + + /** + * Logs a throwing message at DEBUG level. + * + * @param logger logger, may not be null. + * @param sourceClass source class, may be null. + * @param sourceMethod method, may be null. + * @param thrown throwable, may be null. + */ + public static void throwing( + final Logger logger, + final String sourceClass, + final String sourceMethod, + final Throwable thrown) { + if (logger.isDebugEnabled()) { + logger.callAppenders(new LoggingEvent(FQCN, logger, Level.DEBUG, + sourceClass + "." + sourceMethod + " THROW", thrown)); + } + } +} diff --git a/src/main/java/org/apache/log4j/Logger.java b/src/main/java/org/apache/log4j/Logger.java index b15e4c5557..cbd9e8618a 100644 --- a/src/main/java/org/apache/log4j/Logger.java +++ b/src/main/java/org/apache/log4j/Logger.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,77 +18,74 @@ package org.apache.log4j; import org.apache.log4j.spi.LoggerFactory; -import org.apache.log4j.helpers.MessageFormatter; /** - * This is the central class in the log4j package. Most logging - * operations, except configuration, are done through this class. - *

- * - * @author Ceki Gülcü - * @since log4j 1.2 -*/ + This is the central class in the log4j package. Most logging + operations, except configuration, are done through this class. + + @since log4j 1.2 + + @author Ceki Gülcü */ public class Logger extends Category { + /** - * The fully qualified name of the Logger class. See also the {@link #getFQCN} - * method. - */ + The fully qualified name of the Logger class. See also the + getFQCN method. */ private static final String FQCN = Logger.class.getName(); - /** - * This constructor creates a new Logger instance and sets - * its name. - * - *

- * It is intended to be used by sub-classes only. You should not create - * loggers directly. - *

- * - * @param name The name of the logger. - */ - protected Logger(String name) { + + protected + Logger(String name) { super(name); } /** - * Retrieve a logger by name. If the named logger already exists, then the - * existing instance will be reutrned. Otherwise, a new instance is created. - * - *

By default, loggers do not have a set level but inherit it from their - * ancestors. This is one of the central features of log4j. - *

- * - * @param name The name of the logger to retrieve. + * Retrieve a logger named according to the value of the + * name parameter. If the named logger already exists, + * then the existing instance will be returned. Otherwise, a new + * instance is created. + * + *

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. */ - public static Logger getLogger(String name) { + static + public + Logger getLogger(String name) { return LogManager.getLogger(name); } /** - * Shorthand for {@link #getLogger(Class) getLogger(clazz.getName())}. + * Shorthand for getLogger(clazz.getName()). * - * @param clazz The name of clazz will be used as the name of - * the logger to retrieve. See {@link #getLogger(String)} for - * more detailed information. + * @param clazz The name of clazz will be used as the + * name of the logger to retrieve. See {@link #getLogger(String)} + * for more detailed information. */ - public static Logger getLogger(Class clazz) { + static + public + Logger getLogger(Class clazz) { return LogManager.getLogger(clazz.getName()); } + /** - * Return the root of logger for the current hierarchy. - * - *

The root logger is always instantiated and available. It's name is - * "root". - *

- * - *

Nevertheless, note that calling Logger.getLogger("root") - * does not retrieve the root logger but a logger just under root named - * "root". - *

+ * Return the root logger for the current logger repository. + *

+ * The {@link #getName Logger.getName()} method for the root logger always returns + * string value: "root". However, calling + * Logger.getLogger("root") does not retrieve the root + * logger but a logger just under root named "root". + *

+ * In other words, calling this method is the only way to retrieve the + * root logger. */ - public static Logger getRootLogger() { + public + static + Logger getRootLogger() { return LogManager.getRootLogger(); } @@ -105,126 +103,64 @@ public static Logger getRootLogger() { actually create a new Instance. @since 0.8.5 */ - public static Logger getLogger(String name, LoggerFactory factory) { + public + static + Logger getLogger(String name, LoggerFactory factory) { return LogManager.getLogger(name, factory); } - - /** - * Log a message object with the {@link Level#TRACE TRACE} level. - * - * @param message the message object to log. - * @see #debug(Object) for an explanation of the logic applied. - * @since 1.2.12 - */ - public void trace(Object message) { - if (repository.isDisabled(Level.TRACE_INT)) { - return; - } - - if (Level.TRACE.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, Level.TRACE, message, null); - } - } - /** - * Log a message object with the TRACE level including the - * stack trace of the {@link Throwable}t passed as parameter. - * - *

- * See {@link #debug(Object)} form for more detailed information. - *

- * - * @param message the message object to log. - * @param t the exception to log, including its stack trace. - * @since 1.2.12 - */ - public void trace(Object message, Throwable t) { - if (repository.isDisabled(Level.TRACE_INT)) { - return; - } + /** + * Log a message object with the {@link org.apache.log4j.Level#TRACE TRACE} level. + * + * @param message the message object to log. + * @see #debug(Object) for an explanation of the logic applied. + * @since 1.2.12 + */ + public void trace(Object message) { + if (repository.isDisabled(Level.TRACE_INT)) { + return; + } - if (Level.TRACE.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, Level.TRACE, message, t); + if (Level.TRACE.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, Level.TRACE, message, null); + } } - } - /** - * Log a message with the TRACE level with message formatting - * done according to the value of messagePattern and - * arg parameters. - *

- * 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 messagePattern. - * @since 1.3 - */ - public void trace(Object messagePattern, Object arg) { - if (repository.isDisabled(Level.TRACE_INT)) { - return; - } + /** + * Log a message object with the TRACE level including the + * stack trace of the {@link Throwable}t passed as parameter. + * + *

+ * See {@link #debug(Object)} form for more detailed information. + *

+ * + * @param message the message object to log. + * @param t the exception to log, including its stack trace. + * @since 1.2.12 + */ + public void trace(Object message, Throwable t) { + if (repository.isDisabled(Level.TRACE_INT)) { + return; + } - if (Level.TRACE.isGreaterOrEqual(this.getEffectiveLevel())) { - if (messagePattern instanceof String){ - String msgStr = (String) messagePattern; - msgStr = MessageFormatter.format(msgStr, arg); - forcedLog(FQCN, Level.TRACE, 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.TRACE, messagePattern, null); + if (Level.TRACE.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, Level.TRACE, message, t); } } - } - /** - * Log a message with the TRACE level with message formatting - * done according to the messagePattern and the arguments arg1 and arg2. - *

- * 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.3 - */ - public void trace(String messagePattern, Object arg1, Object arg2) { - if (repository.isDisabled(Level.TRACE_INT)) { - return; - } - if (Level.TRACE.isGreaterOrEqual(this.getEffectiveLevel())) { - messagePattern = MessageFormatter.format(messagePattern, arg1, arg2); - forcedLog(FQCN, Level.TRACE, messagePattern, null); - } - } - - /** - * Log a message with the FATAL level with message formatting - * done according to the messagePattern and the arguments arg1 and arg2. - *

- * 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.3 - */ - public void fatal(String messagePattern, Object arg1, Object arg2) { - if (repository.isDisabled(Level.FATAL_INT)) { - return; - } - if (Level.FATAL.isGreaterOrEqual(this.getEffectiveLevel())) { - messagePattern = MessageFormatter.format(messagePattern, arg1, arg2); - forcedLog(FQCN, Level.FATAL, messagePattern, null); + + /** + * Check whether this category is enabled for the TRACE Level. + * @since 1.2.12 + * + * @return boolean - true if this category is enabled for level + * TRACE, false otherwise. + */ + public boolean isTraceEnabled() { + if (repository.isDisabled(Level.TRACE_INT)) { + return false; + } + + return Level.TRACE.isGreaterOrEqual(this.getEffectiveLevel()); } - } - -} -// End of class: Logger.java +} diff --git a/src/main/java/org/apache/log4j/LoggerRepositoryExImpl.java b/src/main/java/org/apache/log4j/LoggerRepositoryExImpl.java deleted file mode 100644 index 984ae4b443..0000000000 --- a/src/main/java/org/apache/log4j/LoggerRepositoryExImpl.java +++ /dev/null @@ -1,668 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j; - -import org.apache.log4j.helpers.LogLog; -import org.apache.log4j.or.ObjectRenderer; -import org.apache.log4j.or.RendererMap; -import org.apache.log4j.plugins.PluginRegistry; -import org.apache.log4j.scheduler.Scheduler; -import org.apache.log4j.spi.ErrorItem; -import org.apache.log4j.spi.HierarchyEventListener; -import org.apache.log4j.spi.LoggerEventListener; -import org.apache.log4j.spi.LoggerFactory; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggerRepositoryEventListener; -import org.apache.log4j.spi.LoggerRepositoryEx; -import org.apache.log4j.spi.RendererSupport; - -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; -import java.util.Vector; - - -/** - * This class implements LoggerRepositoryEx by - * wrapping an existing LoggerRepository implementation - * and implementing the newly added capabilities. -*/ -public final class LoggerRepositoryExImpl - implements LoggerRepositoryEx, RendererSupport { - - /** - * Wrapped logger repository. - */ - private final LoggerRepository repo; - - /** - * Logger factory. Does not affect class of logger - * created by underlying repository. - */ - private LoggerFactory loggerFactory; - - /** - * Renderer support. - */ - private final RendererSupport rendererSupport; - - /** - * List of repository event listeners. - */ - private final ArrayList repositoryEventListeners = new ArrayList(); - /** - * Map of HierarchyEventListener keyed by LoggingEventListener. - */ - private final Map loggerEventListeners = new HashMap(); - /** - * Name of hierarchy. - */ - private String name; - /** - * Plug in registry. - */ - private PluginRegistry pluginRegistry; - /** - * Properties. - */ - private final Map properties = new Hashtable(); - /** - * Scheduler. - */ - private Scheduler scheduler; - - /** The repository can also be used as an object store - * for various objects used by log4j components. - */ - private Map objectMap = new HashMap(); - - - /** - * Error list. - */ - private List errorList = new Vector(); - - /** - * True if hierarchy has not been modified. - */ - private boolean pristine = true; - - /** - Constructs a new logger hierarchy. - - @param repository Base implementation of repository. - - */ - public LoggerRepositoryExImpl(final LoggerRepository repository) { - super(); - if (repository == null) { - throw new NullPointerException("repository"); - } - repo = repository; - if (repository instanceof RendererSupport) { - rendererSupport = (RendererSupport) repository; - } else { - rendererSupport = new RendererSupportImpl(); - } - } - - - /** - Add a {@link LoggerRepositoryEventListener} to the repository. The - listener will be called when repository events occur. - @param listener listener - @since 1.3*/ - public void addLoggerRepositoryEventListener( - final LoggerRepositoryEventListener listener) { - synchronized (repositoryEventListeners) { - if (repositoryEventListeners.contains(listener)) { - LogLog.warn( - "Ignoring attempt to add a previously " - + "registered LoggerRepositoryEventListener."); - } else { - repositoryEventListeners.add(listener); - } - } - } - - - /** - Remove a {@link LoggerRepositoryEventListener} from the repository. - @param listener listener - @since 1.3*/ - public void removeLoggerRepositoryEventListener( - final LoggerRepositoryEventListener listener) { - synchronized (repositoryEventListeners) { - if (!repositoryEventListeners.contains(listener)) { - LogLog.warn( - "Ignoring attempt to remove a " - + "non-registered LoggerRepositoryEventListener."); - } else { - repositoryEventListeners.remove(listener); - } - } - } - - /** - Add a {@link LoggerEventListener} to the repository. The listener - will be called when repository events occur. - @param listener listener - @since 1.3 - */ - public void addLoggerEventListener(final LoggerEventListener listener) { - synchronized (loggerEventListeners) { - if (loggerEventListeners.get(listener) != null) { - LogLog.warn( - "Ignoring attempt to add a previously registerd LoggerEventListener."); - } else { - HierarchyEventListenerProxy proxy = - new HierarchyEventListenerProxy(listener); - loggerEventListeners.put(listener, proxy); - repo.addHierarchyEventListener(proxy); - } - } - } - - /** - Add a {@link org.apache.log4j.spi.HierarchyEventListener} - event to the repository. - @param listener listener - @deprecated Superceded by addLoggerEventListener - */ - public - void addHierarchyEventListener(final HierarchyEventListener listener) { - repo.addHierarchyEventListener(listener); - } - - - /** - Remove a {@link LoggerEventListener} from the repository. - @param listener listener to be removed - @since 1.3*/ - public void removeLoggerEventListener(final LoggerEventListener listener) { - synchronized (loggerEventListeners) { - HierarchyEventListenerProxy proxy = - (HierarchyEventListenerProxy) loggerEventListeners.get(listener); - if (proxy == null) { - LogLog.warn( - "Ignoring attempt to remove a non-registered LoggerEventListener."); - } else { - loggerEventListeners.remove(listener); - proxy.disable(); - } - } - } - - /** - * Issue warning that there are no appenders in hierarchy. - * @param cat logger, not currently used. - */ - public void emitNoAppenderWarning(final Category cat) { - repo.emitNoAppenderWarning(cat); - } - - /** - Check if the named logger exists in the hierarchy. If so return - its reference, otherwise returns null. - - @param loggerName The name of the logger to search for. - @return true if logger exists. - */ - public Logger exists(final String loggerName) { - return repo.exists(loggerName); - } - - /** - * Return the name of this hierarchy. - * @return name of hierarchy - */ - public String getName() { - return name; - } - - /** - * Set the name of this repository. - * - * Note that once named, a repository cannot be rerenamed. - * @since 1.3 - * @param repoName name of hierarchy - */ - public void setName(final String repoName) { - if (name == null) { - name = repoName; - } else if (!name.equals(repoName)) { - throw new IllegalStateException( - "Repository [" + name + "] cannot be renamed as [" + repoName + "]."); - } - } - - /** - * {@inheritDoc} - */ - public Map getProperties() { - return properties; - } - - /** - * {@inheritDoc} - */ - public String getProperty(final String key) { - return (String) properties.get(key); - } - - /** - * Set a property by key and value. The property will be shared by all - * events in this repository. - * @param key property name - * @param value property value - */ - public void setProperty(final String key, - final String value) { - properties.put(key, value); - } - - /** - The string form of {@link #setThreshold(Level)}. - @param levelStr symbolic name for level - */ - public void setThreshold(final String levelStr) { - repo.setThreshold(levelStr); - } - - /** - Enable logging for logging requests with level l or - higher. By default all levels are enabled. - - @param l The minimum level for which logging requests are sent to - their appenders. */ - public void setThreshold(final Level l) { - repo.setThreshold(l); - } - - /** - * {@inheritDoc} - * @since 1.3 - */ - public PluginRegistry getPluginRegistry() { - if (pluginRegistry == null) { - pluginRegistry = new PluginRegistry(this); - } - return pluginRegistry; - } - - - /** - Requests that a appender added event be sent to any registered - {@link LoggerEventListener}. - @param logger The logger to which the appender was added. - @param appender The appender added to the logger. - */ - public void fireAddAppenderEvent(final Category logger, - final Appender appender) { - repo.fireAddAppenderEvent(logger, appender); - } - - - /** - Requests that a appender removed event be sent to any registered - {@link LoggerEventListener}. - @param logger The logger from which the appender was removed. - @param appender The appender removed from the logger. - */ - public void fireRemoveAppenderEvent(final Category logger, - final Appender appender) { - if (repo instanceof Hierarchy) { - ((Hierarchy) repo).fireRemoveAppenderEvent(logger, appender); - } - } - - - /** - Requests that a level changed event be sent to any registered - {@link LoggerEventListener}. - @param logger The logger which changed levels. - @since 1.3*/ - public void fireLevelChangedEvent(final Logger logger) { - } - - /** - * @TODO - Requests that a configuration changed event be sent to any registered - {@link LoggerRepositoryEventListener}. - @since 1.3*/ - public void fireConfigurationChangedEvent() { - } - - - /** - Returns a {@link Level} representation of the enable - state. - @return current threshold level - - @since 1.2 */ - public Level getThreshold() { - return repo.getThreshold(); - } - - - /** - Return a new logger instance named as the first parameter using - the default factory. - -

If a logger of that name already exists, then it will be - returned. Otherwise, a new logger will be instantiated and - then linked with its existing ancestors as well as children. - - @param loggerName The name of the logger to retrieve. - @return logger - - */ - public Logger getLogger(final String loggerName) { - return repo.getLogger(loggerName); - } - - /** - Return a new logger instance named as the first parameter using - factory. - -

If a logger of that name already exists, then it will be - returned. Otherwise, a new logger will be instantiated by the - factory parameter and linked with its existing - ancestors as well as children. - - @param loggerName The name of the logger to retrieve. - @param factory The factory that will make the new logger instance. - @return logger - - */ - public Logger getLogger(final String loggerName, - final LoggerFactory factory) { - return repo.getLogger(loggerName, factory); - } - - /** - Returns all the currently defined categories in this hierarchy as - an {@link java.util.Enumeration Enumeration}. - -

The root logger is not included in the returned - {@link Enumeration}. - @return enumerator of current loggers - */ - public Enumeration getCurrentLoggers() { - return repo.getCurrentLoggers(); - } - - /** - * Return the the list of previously encoutered {@link ErrorItem error items}. - * @return list of errors - */ - public List getErrorList() { - return errorList; - } - - /** - * Add an error item to the list of previously encountered errors. - * @param errorItem error to add to list of errors. - * @since 1.3 - */ - public void addErrorItem(final ErrorItem errorItem) { - getErrorList().add(errorItem); - } - - /** - * Get enumerator over current loggers. - * @return enumerator over current loggers - @deprecated Please use {@link #getCurrentLoggers} instead. - */ - public Enumeration getCurrentCategories() { - return repo.getCurrentCategories(); - } - - /** - Get the renderer map for this hierarchy. - @return renderer map - */ - public RendererMap getRendererMap() { - return rendererSupport.getRendererMap(); - } - - /** - Get the root of this hierarchy. - - @since 0.9.0 - @return root of hierarchy - */ - public Logger getRootLogger() { - return repo.getRootLogger(); - } - - /** - This method will return true if this repository is - disabled for level value passed as parameter and - false otherwise. See also the {@link - #setThreshold(Level) threshold} method. - @param level numeric value for level. - @return true if disabled for specified level - */ - public boolean isDisabled(final int level) { - return repo.isDisabled(level); - } - - /** - Reset all values contained in this hierarchy instance to their - default. This removes all appenders from all categories, sets - the level of all non-root categories to null, - sets their additivity flag to true and sets the level - of the root logger to {@link Level#DEBUG DEBUG}. Moreover, - message disabling is set its default "off" value. - -

Existing categories are not removed. They are just reset. - -

This method should be used sparingly and with care as it will - block all logging until it is completed.

- - @since 0.8.5 */ - public void resetConfiguration() { - repo.resetConfiguration(); - } - - /** - Used by subclasses to add a renderer to the hierarchy passed as parameter. - @param renderedClass class - @param renderer object used to render class. - */ - public void setRenderer(final Class renderedClass, - final ObjectRenderer renderer) { - rendererSupport.setRenderer(renderedClass, renderer); - } - - /** - * {@inheritDoc} - */ - public boolean isPristine() { - return pristine; - } - - /** - * {@inheritDoc} - */ - public void setPristine(final boolean state) { - pristine = state; - } - - /** - Shutting down a hierarchy will safely close and remove - all appenders in all categories including the root logger. - -

Some appenders such as {@link org.apache.log4j.net.SocketAppender} - and {@link AsyncAppender} need to be closed before the - application exists. Otherwise, pending logging events might be - lost. - -

The shutdown method is careful to close nested - appenders before closing regular appenders. This is allows - configurations where a regular appender is attached to a logger - and again to a nested appender. - - @since 1.0 */ - public void shutdown() { - repo.shutdown(); - } - - - /** - * Return this repository's own scheduler. - * The scheduler is lazily instantiated. - * @return this repository's own scheduler. - */ - public Scheduler getScheduler() { - if (scheduler == null) { - scheduler = new Scheduler(); - scheduler.setDaemon(true); - scheduler.start(); - } - return scheduler; - } - - /** - * Puts object by key. - * @param key key, may not be null. - * @param value object to associate with key. - */ - public void putObject(final String key, - final Object value) { - objectMap.put(key, value); - } - - /** - * Get object by key. - * @param key key, may not be null. - * @return object associated with key or null. - */ - public Object getObject(final String key) { - return objectMap.get(key); - } - - /** - * Set logger factory. - * @param factory logger factory. - */ - public void setLoggerFactory(final LoggerFactory factory) { - if (factory == null) { - throw new NullPointerException(); - } - this.loggerFactory = factory; - } - - /** - * Get logger factory. - * @return logger factory. - */ - public LoggerFactory getLoggerFactory() { - return loggerFactory; - } - - /** - * Implementation of RendererSupportImpl if not - * provided by LoggerRepository. - */ - private static final class RendererSupportImpl implements RendererSupport { - /** - * Renderer map. - */ - private final RendererMap renderers = new RendererMap(); - - /** - * Create new instance. - */ - public RendererSupportImpl() { - super(); - } - - /** {@inheritDoc} */ - public RendererMap getRendererMap() { - return renderers; - } - - /** {@inheritDoc} */ - public void setRenderer(final Class renderedClass, - final ObjectRenderer renderer) { - renderers.put(renderedClass, renderer); - } - } - - /** - * Proxy that implements HierarchyEventListener - * and delegates to LoggerEventListener. - */ - private static final class HierarchyEventListenerProxy - implements HierarchyEventListener { - /** - * Wrapper listener. - */ - private LoggerEventListener listener; - - /** - * Creates new instance. - * @param l listener - */ - public HierarchyEventListenerProxy(final LoggerEventListener l) { - super(); - if (l == null) { - throw new NullPointerException("l"); - } - listener = l; - } - - /** {@inheritDoc} */ - public void addAppenderEvent(final Category cat, - final Appender appender) { - if (isEnabled() && cat instanceof Logger) { - listener.appenderAddedEvent((Logger) cat, appender); - } - } - - /** {@inheritDoc} */ - public void removeAppenderEvent(final Category cat, - final Appender appender) { - if (isEnabled() && cat instanceof Logger) { - listener.appenderRemovedEvent((Logger) cat, appender); - } - } - - /** - * Disable forwarding of notifications to - * simulate removal of listener. - */ - public synchronized void disable() { - listener = null; - } - - /** - * Gets whether proxy is enabled. - * @return true if proxy is enabled. - */ - private synchronized boolean isEnabled() { - return listener != null; - } - } - -} diff --git a/src/main/java/org/apache/log4j/MDC.java b/src/main/java/org/apache/log4j/MDC.java index 7f0e5d1c39..c07efed0f0 100644 --- a/src/main/java/org/apache/log4j/MDC.java +++ b/src/main/java/org/apache/log4j/MDC.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,128 +17,196 @@ package org.apache.log4j; +import org.apache.log4j.helpers.Loader; import org.apache.log4j.helpers.ThreadLocalMap; -import java.util.Enumeration; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Hashtable; - /** - The MDC class is similar to the {@link NDC} class except that it is - based on a map instead of a stack. It provides mapped - diagnostic contexts. A Mapped Diagnostic Context, or - MDC in short, is an instrument for distinguishing interleaved log - output from different sources. Log output is typically interleaved - when a server handles multiple clients near-simultaneously. + * The MDC class is similar to the {@link NDC} class except that it is + * based on a map instead of a stack. It provides mapped + * diagnostic contexts. A Mapped Diagnostic Context, or + * MDC in short, is an instrument for distinguishing interleaved log + * output from different sources. Log output is typically interleaved + * when a server handles multiple clients near-simultaneously. + *

+ *

The MDC is managed on a per thread basis. A + * child thread automatically inherits a copy of the mapped + * diagnostic context of its parent. + *

+ *

The MDC class requires JDK 1.2 or above. Under JDK 1.1 the MDC + * will always return empty values but otherwise will not affect or + * harm your application.

+ * + *

Attention: the application is required to clean up. In web applications + * this can happen with creating a Servlet Filter and overriding the + * onFilter method like:

+ * + *
+ * try {
+ *    MDC.put(myKey);
+ *    chain.doFilter(request, response);
+ * } finally {
+ *    MDC.remove(myKey);
+ * }
+ * 
+ * + *

Please also see: {@link http://logging.apache.org/log4j/1.2/faq.html#mdcmemoryleak}

+ * + * @author Ceki Gülcü + * @since 1.2 + */ +public class MDC { -

The MDC is managed on a per thread basis. A - child thread automatically inherits a copy of the mapped - diagnostic context of its parent. + final static MDC mdc = new MDC(); -

The MDC class requires JDK 1.2 or above. Under JDK 1.1 the MDC - will always return empty values but otherwise will not affect or - harm your application. + static final int HT_SIZE = 7; - @since 1.2 + boolean java1; - @author Ceki Gülcü */ -public class MDC { - static final int HT_SIZE = 7; - private static final ThreadLocalMap tlm = new ThreadLocalMap(); - - private MDC() { - } - - /** - * Put a context value (the val parameter) as identified - * with the key parameter into the current thread's - * context map. - * - *

If the current thread does not have a context map it is - * created as a side effect. - * */ - public static void put(String key, String val) { - Hashtable ht = (Hashtable) tlm.get(); - - if (ht == null) { - ht = new Hashtable(HT_SIZE); - tlm.set(ht); + Object tlm; + + private Method removeMethod; + + private MDC() { + java1 = Loader.isJava1(); + if (!java1) { + tlm = new ThreadLocalMap(); + } + + try { + removeMethod = ThreadLocal.class.getMethod("remove", null); + } catch (NoSuchMethodException e) { + // don't do anything - java prior 1.5 + } + } + + /** + * Put a context value (the o parameter) as identified + * with the key parameter into the current thread's + * context map. + *

+ *

If the current thread does not have a context map it is + * created as a side effect. + */ + public static void put(String key, Object o) { + if (mdc != null) { + mdc.put0(key, o); + } + } + + /** + * Get the context identified by the key parameter. + *

+ *

This method has no side effects. + */ + public static Object get(String key) { + if (mdc != null) { + return mdc.get0(key); + } + return null; + } + + /** + * Remove the the context identified by the key + * parameter. + */ + public static void remove(String key) { + if (mdc != null) { + mdc.remove0(key); + } + } + + + /** + * Get the current thread's MDC as a hashtable. This method is + * intended to be used internally. + */ + public static Hashtable getContext() { + if (mdc != null) { + return mdc.getContext0(); + } else { + return null; + } } - ht.put(key, val); - } - - /** - * Please use the {@link #put(String key, String val)} form instead. The 'val' - * parameter needs to be a string. - * - * @param key the key for the contextual information - * @param val is transformed into a string before being placed in the MDC - * @deprecated please use the {@link #put(String key, String val)} form. - */ - public static void put(String key, Object val) { - put(key, val.toString()); - } - - /** - * Get the context identified by the key parameter. - * - *

This method has no side effects. - * */ - public static Object get(String key) { - Hashtable ht = (Hashtable) tlm.get(); - - if ((ht != null) && (key != null)) { - return (String) ht.get(key); - } else { - return null; + /** + * Remove all values from the MDC. + * + * @since 1.2.16 + */ + public static void clear() { + if (mdc != null) { + mdc.clear0(); + } } - } - /** - * Remove the the context identified by the key - * parameter. */ - public static void remove(String key) { - Hashtable ht = (Hashtable) tlm.get(); - if (ht != null) { - ht.remove(key); + private void put0(String key, Object o) { + if (java1 || tlm == null) { + return; + } else { + Hashtable ht = (Hashtable) ((ThreadLocalMap) tlm).get(); + if (ht == null) { + ht = new Hashtable(HT_SIZE); + ((ThreadLocalMap) tlm).set(ht); + } + ht.put(key, o); + } } - } - /** - * Clear all entries in the MDC. - * @since 1.3 - */ - public static void clear() { - Hashtable ht = (Hashtable) tlm.get(); + private Object get0(String key) { + if (java1 || tlm == null) { + return null; + } else { + Hashtable ht = (Hashtable) ((ThreadLocalMap) tlm).get(); + if (ht != null && key != null) { + return ht.get(key); + } else { + return null; + } + } + } + + private void remove0(String key) { + if (!java1 && tlm != null) { + Hashtable ht = (Hashtable) ((ThreadLocalMap) tlm).get(); + if (ht != null) { + ht.remove(key); + // clean up if this was the last key + if (ht.isEmpty()) { + clear0(); + } + } + } + } + + private Hashtable getContext0() { + if (java1 || tlm == null) { + return null; + } else { + return (Hashtable) ((ThreadLocalMap) tlm).get(); + } + } - if (ht != null) { - ht.clear(); + private void clear0() { + if (!java1 && tlm != null) { + Hashtable ht = (Hashtable) ((ThreadLocalMap) tlm).get(); + if (ht != null) { + ht.clear(); + } + if (removeMethod != null) { + // java 1.3/1.4 does not have remove - will suffer from a memory leak + try { + removeMethod.invoke(tlm, null); + } catch (IllegalAccessException e) { + // should not happen + } catch (InvocationTargetException e) { + // should not happen + } + } + } } - } - - /** - * Get the current thread's MDC as a hashtable. This method is - * intended to be used internally. - * */ - public static Hashtable getContext() { - return (Hashtable) tlm.get(); - } - - /** - * Returns the keys in the MDC as an {@link Enumeration}. The returned value can be - * null. - * - * @since version 1.3 - */ - public static Enumeration getKeys() { - Hashtable ht = (Hashtable) tlm.get(); - - if (ht != null) { - return ht.keys(); - } else { - return null; - } - } } diff --git a/src/main/java/org/apache/log4j/NDC.java b/src/main/java/org/apache/log4j/NDC.java index a9df08781e..3b25e99707 100644 --- a/src/main/java/org/apache/log4j/NDC.java +++ b/src/main/java/org/apache/log4j/NDC.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -14,14 +15,17 @@ * limitations under the License. */ - // Contributors: Dan Milstein // Ray Millard -// Ray DeCampo + package org.apache.log4j; +import java.util.Hashtable; import java.util.Stack; +import java.util.Enumeration; +import java.util.Vector; +import org.apache.log4j.helpers.LogLog; /** The NDC class implements nested diagnostic contexts as @@ -59,10 +63,10 @@

  • When leaving a context, call NDC.pop. -

  • As of log4j 1.3, it is no longer necessary to call {@link #remove - NDC.remove()} when exiting a thread.. +

  • When exiting a thread make sure to call {@link #remove + NDC.remove()}. - +

    There is no penalty for forgetting to match each push operation with a corresponding pop, except the obvious mismatch between the real application context @@ -76,30 +80,64 @@ simultaneously, the logs emanating from the same code (belonging to the same category) can still be distinguished because each client request will have a different NDC tag. +

    Heavy duty systems should call the {@link #remove} method when + leaving the run method of a thread. This ensures that the memory + used by the thread can be freed by the Java garbage + collector. There is a mechanism to lazily remove references to dead + threads. In practice, this means that you can be a little sloppy + and sometimes forget to call {@link #remove} before exiting a + thread. +

    A thread may inherit the nested diagnostic context of another (possibly parent) thread using the {@link #inherit inherit} method. A thread may obtain a copy of its NDC with the {@link #cloneStack cloneStack} method and pass the reference to any other thread, in particular to a child. - + @author Ceki Gülcü @since 0.7.0 - + */ + public class NDC { + // The synchronized keyword is not used in this class. This may seem // dangerous, especially since the class will be used by - // multiple-threads. - // This is OK since java Stacks are thread safe. + // multiple-threads. In particular, all threads share the same + // hashtable (the "ht" variable). This is OK since java hashtables + // are thread safe. Same goes for Stacks. + // More importantly, when inheriting diagnostic contexts the child // thread is handed a clone of the parent's NDC. It follows that // each thread has its own NDC (i.e. stack). - private static final ThreadLocal tl = new ThreadLocal(); + static Hashtable ht = new Hashtable(); + + static int pushCounter = 0; // the number of times push has been called + // after the latest call to lazyRemove + + // The number of times we allow push to be called before we call lazyRemove + // 5 is a relatively small number. As such, lazyRemove is not called too + // frequently. We thus avoid the cost of creating an Enumeration too often. + // The higher this number, the longer is the avarage period for which all + // logging calls in all threads are blocked. + static final int REAP_THRESHOLD = 5; + // No instances allowed. - private NDC() { + private NDC() {} + + /** + * Get NDC stack for current thread. + * @return NDC stack for current thread. + */ + private static Stack getCurrentStack() { + if (ht != null) { + return (Stack) ht.get(Thread.currentThread()); + } + return null; } + /** Clear any nested diagnostic information if any. This method is useful in cases where the same thread can be potentially used @@ -107,16 +145,18 @@ private NDC() {

    This method is equivalent to calling the {@link #setMaxDepth} method with a zero maxDepth argument. - + @since 0.8.4c */ - public static void clear() { - Stack stack = (Stack) tl.get(); - - if (stack != null) { - stack.setSize(0); - } + public + static + void clear() { + Stack stack = getCurrentStack(); + if(stack != null) { + stack.setSize(0); + } } + /** Clone the diagnostic context for the current thread. @@ -127,22 +167,22 @@ given thread can supply the stack (i.e. diagnostic context) to a

    The child thread uses the {@link #inherit inherit} method to inherit the parent's diagnostic context. - + @return Stack A clone of the current thread's diagnostic context. */ - public static Stack cloneStack() { - Object o = tl.get(); - - if (o == null) { - return null; + public + static + Stack cloneStack() { + Stack stack = getCurrentStack(); + if(stack == null) { + return null; } else { - Stack stack = (Stack) o; - return (Stack) stack.clone(); } } + /** Inherit the diagnostic context of another thread. @@ -154,7 +194,7 @@ public static Stack cloneStack() {

    The parent's diagnostic context is cloned before being inherited. In other words, once inherited, the two diagnostic contexts can be managed independently. - +

    In java, a child thread cannot obtain a reference to its parent, unless it is directly handed the reference. Consequently, there is no client-transparent way of inheriting diagnostic @@ -163,39 +203,91 @@ public static Stack cloneStack() { @param stack The diagnostic context of the parent thread. */ - public static void inherit(Stack stack) { - if (stack != null) { - tl.set(stack); + public + static + void inherit(Stack stack) { + if(stack != null) { + ht.put(Thread.currentThread(), stack); } } + /** Never use this method directly, use the {@link org.apache.log4j.spi.LoggingEvent#getNDC} method instead. */ - public static String get() { - Stack s = (Stack) tl.get(); - - if ((s != null) && !s.isEmpty()) { - return ((DiagnosticContext) s.peek()).fullMessage; + static + public + String get() { + Stack s = getCurrentStack(); + if(s != null && !s.isEmpty()) { + return ((DiagnosticContext) s.peek()).fullMessage; } else { - return null; + return null; } } - + /** - 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 int getDepth() { - Stack stack = (Stack) tl.get(); - - if (stack == null) { - return 0; + public + static + int getDepth() { + Stack stack = getCurrentStack(); + if(stack == null) { + return 0; } else { - return stack.size(); + return stack.size(); + } + } + + private + static + void lazyRemove() { + if (ht == null) { + return; + } + + // The synchronization on ht is necessary to prevent JDK 1.2.x from + // throwing ConcurrentModificationExceptions at us. This sucks BIG-TIME. + // One solution is to write our own hashtable implementation. + Vector v; + + synchronized(ht) { + // Avoid calling clean-up too often. + if(++pushCounter <= REAP_THRESHOLD) { + return; // We release the lock ASAP. + } else { + pushCounter = 0; // OK let's do some work. + } + + int misses = 0; + v = new Vector(); + 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(enumeration.hasMoreElements() && (misses <= 4)) { + Thread t = (Thread) enumeration.nextElement(); + if(t.isAlive()) { + misses++; + } else { + misses = 0; + v.addElement(t); + } + } + } // synchronized + + int size = v.size(); + for(int i = 0; i < size; i++) { + Thread t = (Thread) v.elementAt(i); + LogLog.debug("Lazy NDC removal for thread [" + t.getName() + "] ("+ + ht.size() + ")."); + ht.remove(t); } } @@ -205,17 +297,18 @@ public static int getDepth() {

    The returned value is the value that was pushed last. If no context is available, then the empty string "" is returned. - + @return String The innermost diagnostic context. - + */ - public static String pop() { - Stack stack = (Stack) tl.get(); - - if ((stack != null) && !stack.isEmpty()) { - return ((DiagnosticContext) stack.pop()).message; + public + static + String pop() { + Stack stack = getCurrentStack(); + if(stack != null && !stack.isEmpty()) { + return ((DiagnosticContext) stack.pop()).message; } else { - return ""; + return ""; } } @@ -225,52 +318,76 @@ public static String pop() {

    The returned value is the value that was pushed last. If no context is available, then the empty string "" is returned. - + @return String The innermost diagnostic context. - + */ - public static String peek() { - Stack stack = (Stack) tl.get(); - - if ((stack != null) && !stack.isEmpty()) { - return ((DiagnosticContext) stack.peek()).message; + public + static + String peek() { + Stack stack = getCurrentStack(); + if(stack != null && !stack.isEmpty()) { + return ((DiagnosticContext) stack.peek()).message; } else { - return ""; + return ""; } } - + /** Push new diagnostic context information for the current thread.

    The contents of the message parameter is - determined solely by the client. - + determined solely by the client. + @param message The new diagnostic context information. */ - public static void push(String message) { - Stack stack = (Stack) tl.get(); - - if (stack == null) { - DiagnosticContext dc = new DiagnosticContext(message, null); + public + static + void push(String message) { + Stack stack = getCurrentStack(); + + if(stack == null) { + DiagnosticContext dc = new DiagnosticContext(message, null); stack = new Stack(); - tl.set(stack); + Thread key = Thread.currentThread(); + ht.put(key, stack); stack.push(dc); } else if (stack.isEmpty()) { - DiagnosticContext dc = new DiagnosticContext(message, null); + DiagnosticContext dc = new DiagnosticContext(message, null); stack.push(dc); } else { DiagnosticContext parent = (DiagnosticContext) stack.peek(); stack.push(new DiagnosticContext(message, parent)); - } + } } /** Remove the diagnostic context for this thread. -

    As of log4j 1.3, the NDC class uses {@link ThreadLocal} - technology to store the context. It is no longer necessary to call this - method. It remains for backwards compatibility. +

    Each thread that created a diagnostic context by calling + {@link #push} should call this method before exiting. Otherwise, + the memory used by the thread cannot be reclaimed by the + VM. + +

    As this is such an important problem in heavy duty systems and + because it is difficult to always guarantee that the remove + method is called before exiting a thread, this method has been + augmented to lazily remove references to dead threads. In + practice, this means that you can be a little sloppy and + occasionally forget to call {@link #remove} before exiting a + thread. However, you must call remove sometime. If + you never call it, then your application is sure to run out of + memory. + */ - public static void remove() { + static + public + void remove() { + if (ht != null) { + ht.remove(Thread.currentThread()); + + // Lazily remove dead-thread references in ht. + lazyRemove(); + } } /** @@ -297,30 +414,32 @@ void foo() { ensures that between the entry and exit of foo the depth of the diagnostic stack is conserved. - + @see #getDepth @since 0.7.5 */ - public static void setMaxDepth(int maxDepth) { - Stack stack = (Stack) tl.get(); - - if ((stack != null) && (maxDepth < stack.size())) { - stack.setSize(maxDepth); + static + public + void setMaxDepth(int maxDepth) { + Stack stack = getCurrentStack(); + if(stack != null && maxDepth < stack.size()) { + stack.setSize(maxDepth); } } - + // ===================================================================== - private static class DiagnosticContext { + private static class DiagnosticContext { + String fullMessage; String message; - + DiagnosticContext(String message, DiagnosticContext parent) { this.message = message; - - if (parent != null) { - fullMessage = parent.fullMessage + ' ' + message; + if(parent != null) { + fullMessage = parent.fullMessage + ' ' + message; } else { - fullMessage = message; + fullMessage = message; } } } } + diff --git a/src/main/java/org/apache/log4j/PatternLayout.java b/src/main/java/org/apache/log4j/PatternLayout.java index 27ed44f9cd..d668a75581 100644 --- a/src/main/java/org/apache/log4j/PatternLayout.java +++ b/src/main/java/org/apache/log4j/PatternLayout.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,30 +17,34 @@ package org.apache.log4j; -import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.helpers.PatternConverter; -import org.apache.log4j.pattern.BridgePatternConverter; import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.helpers.PatternParser; +import org.apache.log4j.helpers.PatternConverter; // Contributors: Nelson Minar // Anders Kristensen /** - *

    A flexible layout configurable with pattern string. The goal of this class - * is to {@link #format format} a {@link LoggingEvent} and return the results - * in a {#link StringBuffer}. The format of the result depends on the - * conversion pattern. - *

    - * - *

    The conversion pattern is closely related to the conversion - * pattern of the printf function in C. A conversion pattern is - * composed of literal text and format control expressions called - * conversion specifiers. - * - *

    Note that you are free to insert any literal text within the - * conversion pattern. - *

    + + A flexible layout configurable with pattern string. + + This code is known to have synchronization and other issues + which are not present in org.apache.log4j.EnhancedPatternLayout. + EnhancedPatternLayout should be used in preference to PatternLayout. + EnhancedPatternLayout is distributed in the log4j extras companion. + +

    The goal of this class is to {@link #format format} a {@link + LoggingEvent} and return the results as a String. The results + depend on the conversion pattern. + +

    The conversion pattern is closely related to the conversion + pattern of the printf function in C. A conversion pattern is + composed of literal text and format control expressions called + conversion specifiers. + +

    You are free to insert any literal text within the conversion + pattern.

    Each conversion specifier starts with a percent sign (%) and is followed by optional format modifiers and a conversion @@ -110,23 +115,39 @@ number of right most components of the class name will be pattern %C{1} will output "SomeClass".

    WARNING Generating the caller class information is - slow. Thus, it's use should be avoided unless execution speed is + slow. Thus, use should be avoided unless execution speed is not an issue. d Used to output the date of - the logging event. The date conversion specifier may be - followed by a set of braces containing a - date and time pattern strings {@link java.text.SimpleDateFormat}, - ABSOLUTE, DATE or ISO8601 - and a set of braces containing a time zone id per - {@link java.util.TimeZone#getTimeZone(String)}. - For example, %d{HH:mm:ss,SSS}, - %d{dd MMM yyyy HH:mm:ss,SSS}, - %d{DATE} or %d{HH:mm:ss}{GMT+0}. If no date format specifier is given then - ISO8601 format is assumed. + the logging event. The date conversion specifier may be + followed by a date format specifier enclosed between + braces. For example, %d{HH:mm:ss,SSS} or + %d{dd MMM yyyy HH:mm:ss,SSS}. If no + date format specifier is given then ISO8601 format is + assumed. + +

    The date format specifier admits the same syntax as the + time pattern string of the {@link + java.text.SimpleDateFormat}. Although part of the standard + JDK, the performance of SimpleDateFormat is + quite poor. + +

    For better results it is recommended to use the log4j date + formatters. These can be specified using one of the strings + "ABSOLUTE", "DATE" and "ISO8601" for specifying {@link + org.apache.log4j.helpers.AbsoluteTimeDateFormat + AbsoluteTimeDateFormat}, {@link + org.apache.log4j.helpers.DateTimeDateFormat DateTimeDateFormat} + and respectively {@link + org.apache.log4j.helpers.ISO8601DateFormat + ISO8601DateFormat}. For example, %d{ISO8601} or + %d{ABSOLUTE}. + +

    These dedicated date formatters perform significantly + better than {@link java.text.SimpleDateFormat}. @@ -137,7 +158,7 @@ number of right most components of the class name will be issued.

    WARNING Generating caller location information is - extremely slow. Its use should be avoided unless execution speed + extremely slow and should be avoided unless execution speed is not an issue. @@ -153,8 +174,8 @@ number of right most components of the class name will be method followed by the callers source the file name and line number between parentheses. -

    The location information can be very useful. However, it's - generation is extremely slow. It's use should be avoided +

    The location information can be very useful. However, its + generation is extremely slow and should be avoided unless execution speed is not an issue. @@ -167,7 +188,7 @@ number of right most components of the class name will be was issued.

    WARNING Generating caller location information is - extremely slow. It's use should be avoided unless execution speed + extremely slow and should be avoided unless execution speed is not an issue. @@ -186,7 +207,7 @@ number of right most components of the class name will be issued.

    WARNING Generating caller location information is - extremely slow. It's use should be avoided unless execution speed + extremely slow and should be avoided unless execution speed is not an issue. @@ -214,7 +235,7 @@ number of right most components of the class name will be r - Used to output the number of milliseconds elapsed since the construction + Used to output the number of milliseconds elapsed from the construction of the layout until the creation of the logging event. @@ -240,46 +261,18 @@ Used to output the NDC (nested diagnostic context) associated X - - + +

    Used to output the MDC (mapped diagnostic context) associated with the thread that generated the logging event. The X - conversion character can be followed by the key for the + conversion character must be followed by the key for the map placed between braces, as in %X{clientNumber} where clientNumber is the key. The value in the MDC - corresponding to the key will be output. If no additional sub-option - is specified, then the entire contents of the MDC key value pair set - is output using a format {{key1,val1},{key2,val2}}

    - + corresponding to the key will be output.

    +

    See {@link MDC} class for more details.

    - - - - - - properties - - -

    Used to output the Properties associated - with the logging event. The properties - conversion word can be followed by the key for the - map placed between braces, as in %properties{application} where - application is the key. The value in the Properties bundle - corresponding to the key will be output. If no additional sub-option - is specified, then the entire contents of the Properties key value pair set - is output using a format {{key1,val1},{key2,val2}}

    - - - - - throwable - - -

    Used to output the Throwable trace that has been bound to the LoggingEvent, by - default this will output the full trace as one would normally find by a call to Throwable.printStackTrace(). - The throwable conversion word can be followed by an option in the form %throwable{short} - which will only output the first line of the ThrowableInformation.

    + @@ -404,49 +397,29 @@ reached. The default is to pad on the left (right justify) but you @since 0.8.2 */ public class PatternLayout extends Layout { + + /** Default pattern string for log output. Currently set to the string "%m%n" which just prints the application supplied message. */ - public static final String DEFAULT_CONVERSION_PATTERN = "%m%n"; + public final static String DEFAULT_CONVERSION_PATTERN ="%m%n"; /** A conversion pattern equivalent to the TTCCCLayout. Current value is %r [%t] %p %c %x - %m%n. */ - public static final String TTCC_CONVERSION_PATTERN = - "%r [%t] %p %c %x - %m%n"; + public final static String TTCC_CONVERSION_PATTERN + = "%r [%t] %p %c %x - %m%n"; - /** - * Initial size of internal buffer, no longer used. - * @deprecated since 1.3 - */ - protected final int BUF_SIZE = 256; - /** - * Maximum capacity of internal buffer, no longer used. - * @deprecated since 1.3 - */ + protected final int BUF_SIZE = 256; protected final int MAX_CAPACITY = 1024; - /** - * Customized pattern conversion rules are stored under this key in the - * {@link org.apache.log4j.spi.LoggerRepository LoggerRepository} object store. - */ - public static final String PATTERN_RULE_REGISTRY = "PATTERN_RULE_REGISTRY"; + // output buffer appended to when format() is invoked + private StringBuffer sbuf = new StringBuffer(BUF_SIZE); - /** - * Initial converter for pattern. - */ - private PatternConverter head; + private String pattern; - /** - * Conversion pattern. - */ - private String conversionPattern; - - /** - * True if any element in pattern formats information from exceptions. - */ - private boolean handlesExceptions; + private PatternConverter head; /** Constructs a PatternLayout using the DEFAULT_LAYOUT_PATTERN. @@ -458,89 +431,81 @@ public PatternLayout() { } /** - * Constructs a PatternLayout using the supplied conversion pattern. - * @param pattern conversion pattern. + Constructs a PatternLayout using the supplied conversion pattern. */ - public PatternLayout(final String pattern) { - this.conversionPattern = pattern; - head = createPatternParser( - (pattern == null) ? DEFAULT_CONVERSION_PATTERN : pattern).parse(); - if (head instanceof BridgePatternConverter) { - handlesExceptions = !((BridgePatternConverter) head).ignoresThrowable(); - } else { - handlesExceptions = false; - } + public PatternLayout(String pattern) { + this.pattern = pattern; + head = createPatternParser((pattern == null) ? DEFAULT_CONVERSION_PATTERN : + pattern).parse(); } - /** - * Set the ConversionPattern option. This is the string which - * controls formatting and consists of a mix of literal content and - * conversion specifiers. - * - * @param conversionPattern conversion pattern. - */ - public void setConversionPattern(final String conversionPattern) { - this.conversionPattern = - OptionConverter.convertSpecialChars(conversionPattern); - head = createPatternParser(this.conversionPattern).parse(); - if (head instanceof BridgePatternConverter) { - handlesExceptions = !((BridgePatternConverter) head).ignoresThrowable(); - } else { - handlesExceptions = false; - } + /** + Set the ConversionPattern option. This is the string which + controls formatting and consists of a mix of literal content and + conversion specifiers. + */ + public + void setConversionPattern(String conversionPattern) { + pattern = conversionPattern; + head = createPatternParser(conversionPattern).parse(); } /** - * Returns the value of the ConversionPattern option. - * @return conversion pattern. + Returns the value of the ConversionPattern option. */ - public String getConversionPattern() { - return conversionPattern; + public + String getConversionPattern() { + return pattern; } + /** + Does not do anything as options become effective + */ + public + void activateOptions() { + // nothing to do. + } - /** - Returns PatternParser used to parse the conversion string. Subclasses - may override this to return a subclass of PatternParser which recognize - custom conversion characters. - - @since 0.9.0 - */ - protected org.apache.log4j.helpers.PatternParser createPatternParser(String pattern) { - return new org.apache.log4j.pattern.BridgePatternParser(pattern, - repository, getLogger()); - } + /** + The PatternLayout does not handle the throwable contained within + {@link LoggingEvent LoggingEvents}. Thus, it returns + true. + @since 0.8.4 */ + public + boolean ignoresThrowable() { + return true; + } /** - Activates the conversion pattern. Do not forget to call this method after - you change the parameters of the PatternLayout instance. + Returns PatternParser used to parse the conversion string. Subclasses + may override this to return a subclass of PatternParser which recognize + custom conversion characters. + + @since 0.9.0 */ - public void activateOptions() { - // nothing to do. + protected PatternParser createPatternParser(String pattern) { + return new PatternParser(pattern); } /** - * Formats a logging event to a writer. - * @param event logging event to be formatted. + Produces a formatted string as specified by the conversion pattern. */ - public String format(final LoggingEvent event) { - StringBuffer buf = new StringBuffer(); - for(PatternConverter c = head; - c != null; - c = c.next) { - c.format(buf, event); - } - return buf.toString(); - } + public String format(LoggingEvent event) { + // Reset working stringbuffer + if(sbuf.capacity() > MAX_CAPACITY) { + sbuf = new StringBuffer(BUF_SIZE); + } else { + sbuf.setLength(0); + } - /** - * Will return false if any of the conversion specifiers in the pattern - * handles {@link Exception Exceptions}. - * @return true if the pattern formats any information from exceptions. - */ - public boolean ignoresThrowable() { - return !handlesExceptions; + PatternConverter c = head; + + while(c != null) { + c.format(sbuf, event); + c = c.next; + } + return sbuf.toString(); } } diff --git a/src/main/java/org/apache/log4j/Priority.java b/src/main/java/org/apache/log4j/Priority.java index a0cba74845..53e94b4d4e 100644 --- a/src/main/java/org/apache/log4j/Priority.java +++ b/src/main/java/org/apache/log4j/Priority.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -14,244 +15,179 @@ * limitations under the License. */ - // Contributors: Kitching Simon -package org.apache.log4j; +package org.apache.log4j; /** - * Refrain from using this class directly, use the - * {@link Level} class instead. - * - * @author Ceki Gülcü - */ -public class Priority { - /** - * The integer value of this Level instance. - */ - transient int level; - /** - * The label of this Level instance. - */ - transient String levelStr; - /** - * The UNIX SysLog equivalent value of this Level instance. - */ - transient int syslogEquivalent; - - /** - * OFF level integer value. - */ - public static final int OFF_INT = Integer.MAX_VALUE; - - /** - * FATAL level integer value. - */ - public static final int FATAL_INT = 50000; - - /** - * ERROR level integer value. - */ - public static final int ERROR_INT = 40000; - - /** - * WARN level integer value. - */ - public static final int WARN_INT = 30000; - - /** - * INFO level integer value. - */ - public static final int INFO_INT = 20000; - - /** - * DEBUG level integer value. - */ - public static final int DEBUG_INT = 10000; + Refrain from using this class directly, use + the {@link Level} class instead. + @author Ceki Gülcü */ +public class Priority { - /** - * ALL level integer value. - */ - public static final int ALL_INT = Integer.MIN_VALUE; + transient int level; + transient String levelStr; + transient int syslogEquivalent; - + public final static int OFF_INT = Integer.MAX_VALUE; + public final static int FATAL_INT = 50000; + public final static int ERROR_INT = 40000; + public final static int WARN_INT = 30000; + public final static int INFO_INT = 20000; + public final static int DEBUG_INT = 10000; + //public final static int FINE_INT = DEBUG_INT; + public final static int ALL_INT = Integer.MIN_VALUE; /** - The FATAL level designates very severe error - events that will presumably lead the application to abort. - @deprecated + * @deprecated Use {@link Level#FATAL} instead. */ - public static final Priority FATAL = new Level(FATAL_INT, "FATAL", 0); + final static public Priority FATAL = new Level(FATAL_INT, "FATAL", 0); /** - The ERROR level designates error events that - might still allow the application to continue running. - @deprecated + * @deprecated Use {@link Level#ERROR} instead. */ - public static final Priority ERROR = new Level(ERROR_INT, "ERROR", 3); + final static public Priority ERROR = new Level(ERROR_INT, "ERROR", 3); /** - The WARN level designates potentially harmful situations. - @deprecated - */ - public static final Priority WARN = new Level(WARN_INT, "WARN", 4); + * @deprecated Use {@link Level#WARN} instead. + */ + final static public Priority WARN = new Level(WARN_INT, "WARN", 4); /** - The INFO level designates informational messages - that highlight the progress of the application at coarse-grained - level. - @deprecated + * @deprecated Use {@link Level#INFO} instead. */ - public static final Priority INFO = new Level(INFO_INT, "INFO", 6); + final static public Priority INFO = new Level(INFO_INT, "INFO", 6); /** - The DEBUG priority designates fine-grained - informational events that are most useful to debug an - application. - @deprecated + * @deprecated Use {@link Level#DEBUG} instead. */ - public static final Priority DEBUG = new Level(DEBUG_INT, "DEBUG", 7); - - /** - * Default constructor for deserialization. - */ - protected Priority() { - level = Level.DEBUG_INT; - levelStr = "DEBUG"; - syslogEquivalent = 7; - } - - /** - Instantiate a level object. - */ - protected - Priority(int level, String levelStr, int syslogEquivalent) { - this.level = level; - this.levelStr = levelStr; - this.syslogEquivalent = syslogEquivalent; - } + final static public Priority DEBUG = new Level(DEBUG_INT, "DEBUG", 7); - /** - Two priorities are equal if their level fields are equal. - @since 1.2 - */ - public - boolean equals(Object o) { - if(o instanceof Priority) { - Priority r = (Priority) o; - return (this.level == r.level); - } else { - return false; - } - } - - /** - * Returns a hash code based on the level. - */ - public - int hashCode() { - return level; - } - - /** - Return the syslog equivalent of this priority as an integer. - */ - public - final - int getSyslogEquivalent() { - return syslogEquivalent; - } - - - - /** - Returns true if this level has a higher or equal - level than the level passed as argument, false - otherwise. + /** + * Default constructor for deserialization. + */ + protected Priority() { + level = DEBUG_INT; + levelStr = "DEBUG"; + syslogEquivalent = 7; + } -

    You should think twice before overriding the default - implementation of isGreaterOrEqual method. + /** + Instantiate a level object. + */ + protected + Priority(int level, String levelStr, int syslogEquivalent) { + this.level = level; + this.levelStr = levelStr; + this.syslogEquivalent = syslogEquivalent; + } - */ - public - boolean isGreaterOrEqual(Priority r) { - return level >= r.level; + /** + Two priorities are equal if their level fields are equal. + @since 1.2 + */ + public + boolean equals(Object o) { + if(o instanceof Priority) { + Priority r = (Priority) o; + return (this.level == r.level); + } else { + return false; } + } - /** - Return all possible priorities as an array of Level objects in - descending order. + /** + Return the syslog equivalent of this priority as an integer. + */ + public + final + int getSyslogEquivalent() { + return syslogEquivalent; + } - @deprecated This method will be removed with no replacement. - */ - public - static - Priority[] getAllPossiblePriorities() { - return new Priority[] {Priority.FATAL, Priority.ERROR, Level.WARN, - Priority.INFO, Priority.DEBUG}; - } + + /** + Returns true if this level has a higher or equal + level than the level passed as argument, false + otherwise. + +

    You should think twice before overriding the default + implementation of isGreaterOrEqual method. - /** - Returns the string representation of this priority. - */ - final - public - String toString() { - return levelStr; - } + */ + public + boolean isGreaterOrEqual(Priority r) { + return level >= r.level; + } - /** - Returns the integer representation of this level. - */ - public - final - int toInt() { - return level; - } + /** + Return all possible priorities as an array of Level objects in + descending order. + @deprecated This method will be removed with no replacement. + */ + public + static + Priority[] getAllPossiblePriorities() { + return new Priority[] {Priority.FATAL, Priority.ERROR, Level.WARN, + Priority.INFO, Priority.DEBUG}; + } /** - 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.} + Returns the string representation of this priority. + */ + final + public + String toString() { + return levelStr; + } + /** + Returns the integer representation of this level. + */ + public + final + int toInt() { + return level; + } + /** + * @deprecated Please use the {@link Level#toLevel(String)} method instead. */ - public static Priority toPriority(String sArg) { + public + static + Priority toPriority(String sArg) { return Level.toLevel(sArg); } /** - Convert an integer passed as argument to a priority. If the - conversion fails, then this method returns {@link #DEBUG}. - @deprecated - - */ - public static Priority toPriority(int val) { + * @deprecated Please use the {@link Level#toLevel(int)} method instead. + */ + public + static + Priority toPriority(int val) { return toPriority(val, Priority.DEBUG); } /** - Convert an integer passed as argument to a priority. If the - conversion fails, then this method returns the specified default. - @deprecated + * @deprecated Please use the {@link Level#toLevel(int, Level)} method instead. */ - public static Priority toPriority(int val, Priority defaultPriority) { + public + static + Priority toPriority(int val, Priority defaultPriority) { return Level.toLevel(val, (Level) defaultPriority); } /** - Convert the string passed as argument to a priority. If the - conversion fails, then this method returns the value of - defaultPriority. - @deprecated - */ - public static Priority toPriority(String sArg, Priority defaultPriority) { + * @deprecated Please use the {@link Level#toLevel(String, Level)} method instead. + */ + public + static + Priority toPriority(String sArg, Priority defaultPriority) { return Level.toLevel(sArg, (Level) defaultPriority); } } diff --git a/src/main/java/org/apache/log4j/PropertyConfigurator.java b/src/main/java/org/apache/log4j/PropertyConfigurator.java index 5557437b2f..3e5cc26147 100644 --- a/src/main/java/org/apache/log4j/PropertyConfigurator.java +++ b/src/main/java/org/apache/log4j/PropertyConfigurator.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -14,35 +15,40 @@ * limitations under the License. */ -// Contibutors: "Luke Blanshard" + +// Contributors: "Luke Blanshard" // "Mark DONSZELMANN" // Anders Kristensen -package org.apache.log4j; - -import org.apache.log4j.config.ConfiguratorBase; -import org.apache.log4j.config.PropertySetter; -import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.helpers.Constants; -import org.apache.log4j.or.RendererMap; -//import org.apache.log4j.config.PropertySetterException; -import org.apache.log4j.spi.*; -import org.apache.log4j.watchdog.FileWatchdog; -import org.apache.log4j.plugins.PluginRegistry; +package org.apache.log4j; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; - +import java.io.InterruptedIOException; +import java.net.URLConnection; import java.util.Enumeration; import java.util.Hashtable; -import java.util.List; import java.util.Properties; import java.util.StringTokenizer; import java.util.Vector; -import java.net.URL; -import java.net.MalformedURLException; +import java.util.Iterator; +import java.util.Map; +import org.apache.log4j.config.PropertySetter; +import org.apache.log4j.helpers.FileWatchdog; +import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.helpers.OptionConverter; +import org.apache.log4j.or.RendererMap; +import org.apache.log4j.spi.Configurator; +import org.apache.log4j.spi.Filter; +import org.apache.log4j.spi.LoggerFactory; +import org.apache.log4j.spi.LoggerRepository; +import org.apache.log4j.spi.OptionHandler; +import org.apache.log4j.spi.RendererSupport; +import org.apache.log4j.spi.ThrowableRenderer; +import org.apache.log4j.spi.ThrowableRendererSupport; +import org.apache.log4j.spi.ErrorHandler; /** Allows the configuration of log4j from an external file. See @@ -62,8 +68,8 @@

    The PropertyConfigurator does not handle the advanced configuration features supported by the {@link org.apache.log4j.xml.DOMConfigurator DOMConfigurator} such as - support for {@link org.apache.log4j.spi.Filter Filters}, nested - appenders such as the {@link org.apache.log4j.AsyncAppender + support custom {@link org.apache.log4j.spi.ErrorHandler ErrorHandlers}, + nested appenders such as the {@link org.apache.log4j.AsyncAppender AsyncAppender}, etc.

    All option values admit variable substitution. The @@ -84,37 +90,40 @@ @author Ceki Gülcü @author Anders Kristensen @since 0.8.1 */ -public class PropertyConfigurator extends ConfiguratorBase - implements ConfiguratorEx { - static final String CATEGORY_PREFIX = "log4j.category."; - static final String LOGGER_PREFIX = "log4j.logger."; - static final String FACTORY_PREFIX = "log4j.factory"; - static final String ADDITIVITY_PREFIX = "log4j.additivity."; - static final String ROOT_CATEGORY_PREFIX = "log4j.rootCategory"; - static final String ROOT_LOGGER_PREFIX = "log4j.rootLogger"; - static final String APPENDER_PREFIX = "log4j.appender."; - static final String RENDERER_PREFIX = "log4j.renderer."; - static final String THRESHOLD_PREFIX = "log4j.threshold"; +public class PropertyConfigurator implements Configurator { /** - * Makes log4j reset the configuration by setting it to true. - */ - static final String RESET_KEY = "log4j.reset"; + Used internally to keep track of configured appenders. + */ + protected Hashtable registry = new Hashtable(11); + private LoggerRepository repository; + protected LoggerFactory loggerFactory = new DefaultCategoryFactory(); + + static final String CATEGORY_PREFIX = "log4j.category."; + static final String LOGGER_PREFIX = "log4j.logger."; + static final String FACTORY_PREFIX = "log4j.factory"; + static final String ADDITIVITY_PREFIX = "log4j.additivity."; + static final String ROOT_CATEGORY_PREFIX = "log4j.rootCategory"; + static final String ROOT_LOGGER_PREFIX = "log4j.rootLogger"; + static final String APPENDER_PREFIX = "log4j.appender."; + static final String RENDERER_PREFIX = "log4j.renderer."; + static final String THRESHOLD_PREFIX = "log4j.threshold"; + private static final String THROWABLE_RENDERER_PREFIX = "log4j.throwableRenderer"; + private static final String LOGGER_REF = "logger-ref"; + private static final String ROOT_REF = "root-ref"; + private static final String APPENDER_REF_TAG = "appender-ref"; + /** Key for specifying the {@link org.apache.log4j.spi.LoggerFactory LoggerFactory}. Currently set to "log4j.loggerFactory". */ public static final String LOGGER_FACTORY_KEY = "log4j.loggerFactory"; - private static final String INTERNAL_ROOT_NAME = "root"; - private static Object watchdogLock = new Object(); - private static FileWatchdog fileWatchdog = null; + /** + * If property set to true, then hierarchy will be reset before configuration. + */ + private static final String RESET_KEY = "log4j.reset"; - /** - Used internally to keep track of configured appenders. - */ - protected Hashtable registry = new Hashtable(11); - protected LoggerFactory loggerFactory = new DefaultLoggerFactory(); - protected List errorList = new Vector(); + static final private String INTERNAL_ROOT_NAME = "root"; /** Read configuration from a file. The existing configuration is @@ -167,6 +176,29 @@ public class PropertyConfigurator extends ConfiguratorBase log4j.appender.appenderName.layout.optionN=valueN + The syntax for adding {@link Filter}s to an appender is: +

    +    log4j.appender.appenderName.filter.ID=fully.qualified.name.of.filter.class
    +    log4j.appender.appenderName.filter.ID.option1=value1
    +    ...
    +    log4j.appender.appenderName.filter.ID.optionN=valueN
    +    
    + The first line defines the class name of the filter identified by ID; + subsequent lines with the same ID specify filter option - value + pairs. Multiple filters are added to the appender in the lexicographic + order of IDs. + + The syntax for adding an {@link ErrorHandler} to an appender is: +
    +    log4j.appender.appenderName.errorhandler=fully.qualified.name.of.filter.class
    +    log4j.appender.appenderName.errorhandler.root-ref={true|false}
    +    log4j.appender.appenderName.errorhandler.logger-ref=loggerName
    +    log4j.appender.appenderName.errorhandler.appender-ref=appenderName
    +    log4j.appender.appenderName.errorhandler.option1=value1
    +    ...
    +    log4j.appender.appenderName.errorhandler.optionN=valueN
    +    
    +

    Configuring loggers

    The syntax for configuring the root logger is: @@ -236,11 +268,34 @@ public class PropertyConfigurator extends ConfiguratorBase log4j.renderer.my.Fruit=my.FruitRenderer +

    ThrowableRenderer

    + + You can customize the way an instance of Throwable is + converted to String before being logged. This is done by + specifying an {@link org.apache.log4j.spi.ThrowableRenderer ThrowableRenderer}. + +

    The syntax is: + +

    +   log4j.throwableRenderer=fully.qualified.name.of.rendering.class
    +   log4j.throwableRenderer.paramName=paramValue
    +   
    + + As in, +
    +   log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer
    +   
    +

    Logger Factories

    The usage of custom logger factories is discouraged and no longer documented. +

    Resetting Hierarchy

    + + The hierarchy will be reset before configuration when + log4j.reset=true is present in the properties file. +

    Example

    An example configuration is given below. Other configuration @@ -261,7 +316,7 @@ public class PropertyConfigurator extends ConfiguratorBase # milliseconds, followed by the level of the log request, # followed by the two rightmost components of the logger name, # followed by the callers method name, followed by the line number, - # the nested disgnostic context and finally the message itself. + # the nested diagnostic context and finally the message itself. # Refer to the documentation of {@link PatternLayout} for further information # on the syntax of the ConversionPattern key. log4j.appender.A1.layout=org.apache.log4j.PatternLayout @@ -284,7 +339,7 @@ public class PropertyConfigurator extends ConfiguratorBase # Logger definitions: # The SECURITY logger inherits is level from root. However, it's output # will go to A1 appender defined above. It's additivity is non-cumulative. - log4j.logger.SECURITY=INHERITED, A1 + log4j.logger.SECURITY=INHERIT, A1 log4j.additivity.SECURITY=false # Only warnings or above will be logged for the logger "SECURITY.access". @@ -295,7 +350,7 @@ public class PropertyConfigurator extends ConfiguratorBase # The logger "class.of.the.day" inherits its level from the # logger hierarchy. Output will go to the appender's of the root # logger, A2 in this case. - log4j.logger.class.of.the.day=INHERITED + log4j.logger.class.of.the.day=INHERIT

    Refer to the setOption method in each Appender and @@ -309,230 +364,223 @@ public class PropertyConfigurator extends ConfiguratorBase configuration information is stored. */ - public void doConfigure(String configFileName, LoggerRepository repo) { + public + void doConfigure(String configFileName, LoggerRepository hierarchy) { Properties props = new Properties(); - - FileInputStream istream = null; - try { + FileInputStream istream = null; + try { istream = new FileInputStream(configFileName); props.load(istream); - } catch (Exception e) { - String errMsg = - "Could not read configuration file [" + configFileName + "]."; - addError(new ErrorItem(errMsg, e)); - getLogger(repo).error(errMsg, e); + istream.close(); + } + catch (Exception e) { + if (e instanceof InterruptedIOException || e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } + LogLog.error("Could not read configuration file ["+configFileName+"].", e); + LogLog.error("Ignoring configuration file [" + configFileName+"]."); return; } finally { if(istream != null) { try { istream.close(); - } catch(IOException ignored) { + } catch(InterruptedIOException ignore) { + Thread.currentThread().interrupt(); + } catch(Throwable ignore) { } + } } - // If we reach here, then the config file is alright. - doConfigure(props, repo); + doConfigure(props, hierarchy); } /** */ - public static void configure(String configFilename) { - new PropertyConfigurator().doConfigure( - configFilename, LogManager.getLoggerRepository()); + static + public + void configure(String configFilename) { + new PropertyConfigurator().doConfigure(configFilename, + LogManager.getLoggerRepository()); } /** - Read configuration options from url configURL. + Read configuration options from url configURL. + + @since 0.8.2 +*/ +public +static +void configure(java.net.URL configURL) { + new PropertyConfigurator().doConfigure(configURL, + LogManager.getLoggerRepository()); +} + +/** +Reads configuration options from an InputStream. + +@since 1.2.17 +*/ +public +static +void configure(InputStream inputStream) { +new PropertyConfigurator().doConfigure(inputStream, + LogManager.getLoggerRepository()); +} - @since 0.8.2 - */ - public static void configure(java.net.URL configURL) { - new PropertyConfigurator().doConfigure( - configURL, LogManager.getLoggerRepository()); - } /** Read configuration options from properties. See {@link #doConfigure(String, LoggerRepository)} for the expected format. */ - public static void configure(Properties properties) { - new PropertyConfigurator().doConfigure( - properties, LogManager.getLoggerRepository()); + static + public + void configure(Properties properties) { + new PropertyConfigurator().doConfigure(properties, + LogManager.getLoggerRepository()); } /** - Like {@link #configureAndWatch(String, long)} except that the - default delay of 60 seconds is used. + Like {@link #configureAndWatch(String, long)} except that the + default delay as defined by {@link FileWatchdog#DEFAULT_DELAY} is + used. - @deprecated Use org.apache.log4j.watchdog.FileWatchdog directly. - - @param configFilename A log4j configuration file in XML format. + @param configFilename A file in key=value format. */ - static public void configureAndWatch(String configFilename) { - configureAndWatch(configFilename, 60000); + static + public + void configureAndWatch(String configFilename) { + configureAndWatch(configFilename, FileWatchdog.DEFAULT_DELAY); } - /** - Read the configuration file configFilename if it - exists. Moreover, a thread will be created that will periodically - check if configFilename has been created or - modified. The period is determined by the delay - argument. If a change or file creation is detected, then - configFilename is read to configure log4j. - - @deprecated Use org.apache.log4j.watchdog.FileWatchdog directly. - @param configFilename A log4j configuration file in XML format. - @param delay The delay in milliseconds to wait between each check. + /** + Read the configuration file configFilename if it + exists. Moreover, a thread will be created that will periodically + check if configFilename has been created or + modified. The period is determined by the delay + argument. If a change or file creation is detected, then + configFilename is read to configure log4j. + + @param configFilename A file in key=value format. + @param delay The delay in milliseconds to wait between each check. */ - static public void configureAndWatch(String configFilename, long delay) { - synchronized(watchdogLock) { - PluginRegistry pluginRegistry = - ((LoggerRepositoryEx)LogManager.getLoggerRepository()).getPluginRegistry(); - - // stop existing watchdog - if (fileWatchdog != null) { - pluginRegistry.stopPlugin(fileWatchdog.getName()); - fileWatchdog = null; - } - - // create the watchdog - fileWatchdog = new FileWatchdog(); - fileWatchdog.setName("PropertyConfigurator.FileWatchdog"); - fileWatchdog.setConfigurator(PropertyConfigurator.class.getName()); - fileWatchdog.setFile(configFilename); - fileWatchdog.setInterval(delay); - fileWatchdog.setInitialConfigure(true); - - // register and start the watchdog - pluginRegistry.addPlugin(fileWatchdog); - fileWatchdog.activateOptions(); - } + static + public + void configureAndWatch(String configFilename, long delay) { + PropertyWatchdog pdog = new PropertyWatchdog(configFilename); + pdog.setDelay(delay); + pdog.start(); } + /** Read configuration options from properties. See {@link #doConfigure(String, LoggerRepository)} for the expected format. */ - public void doConfigure(Properties properties, LoggerRepository repository) { - String debug = properties.getProperty(DEBUG_KEY); - String reset = properties.getProperty(RESET_KEY); - - try { - // we start by attaching a temporary list appender - attachListAppender(repository); - - if (OptionConverter.toBoolean(reset, false)) { - repository.resetConfiguration(); - } - - boolean attachedConsoleAppender = false; - if ((debug != null) && OptionConverter.toBoolean(debug, true)) { - attachTemporaryConsoleAppender(repository); - attachedConsoleAppender = true; - } - - // As soon as we start configuration process, the pristine flag is set to - // false. - if(repository instanceof LoggerRepositoryEx) { - ((LoggerRepositoryEx) repository).setPristine(false); - } - - - String thresholdStr = - OptionConverter.findAndSubst(THRESHOLD_PREFIX, properties); - - if (thresholdStr != null) { - repository.setThreshold( - OptionConverter.toLevel(thresholdStr, Level.ALL)); - getLogger(repository).debug( - "Hierarchy threshold set to [" + repository.getThreshold() + "]."); - } - - configureRootCategory(properties, repository); - configureLoggerFactory(properties, repository); - parseCatsAndRenderers(properties, repository); + public + void doConfigure(Properties properties, LoggerRepository hierarchy) { + repository = hierarchy; + String value = properties.getProperty(LogLog.DEBUG_KEY); + if(value == null) { + value = properties.getProperty("log4j.configDebug"); + if(value != null) { + LogLog.warn("[log4j.configDebug] is deprecated. Use [log4j.debug] instead."); + } + } - getLogger(repository).debug("Finished configuring."); + if(value != null) { + LogLog.setInternalDebugging(OptionConverter.toBoolean(value, true)); + } - if (attachedConsoleAppender) { - detachTemporaryConsoleAppender(repository, errorList); - } + // + // if log4j.reset=true then + // reset hierarchy + String reset = properties.getProperty(RESET_KEY); + if (reset != null && OptionConverter.toBoolean(reset, false)) { + hierarchy.resetConfiguration(); + } - // We don't want to hold references to appenders preventing their - // garbage collection. - clearRegistry(); - } finally { - detachListAppender(repository); + String thresholdStr = OptionConverter.findAndSubst(THRESHOLD_PREFIX, + properties); + if(thresholdStr != null) { + hierarchy.setThreshold(OptionConverter.toLevel(thresholdStr, + Level.ALL)); + LogLog.debug("Hierarchy threshold set to ["+hierarchy.getThreshold()+"]."); } + + configureRootCategory(properties, hierarchy); + configureLoggerFactory(properties); + parseCatsAndRenderers(properties, hierarchy); + + LogLog.debug("Finished configuring."); + // We don't want to hold references to appenders preventing their + // garbage collection. + registry.clear(); } /** - * Clears the registry so that we don't hold references to Appender - * objects, which would prevent their garbage collection. + * Read configuration options from an InputStream. + * + * @since 1.2.17 */ - protected void clearRegistry() { - registry.clear(); + public void doConfigure(InputStream inputStream, LoggerRepository hierarchy) { + Properties props = new Properties(); + try { + props.load(inputStream); + } catch (IOException e) { + if (e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.error("Could not read configuration file from InputStream [" + inputStream + + "].", e); + LogLog.error("Ignoring configuration InputStream [" + inputStream +"]."); + return; + } + this.doConfigure(props, hierarchy); } /** Read configuration options from url configURL. */ - public void doConfigure(java.net.URL configURL, LoggerRepository repository) { + public + void doConfigure(java.net.URL configURL, LoggerRepository hierarchy) { Properties props = new Properties(); - getLogger(repository).debug( - "Reading configuration from URL {}", configURL); - - InputStream in = null; + LogLog.debug("Reading configuration from URL " + configURL); + InputStream istream = null; + URLConnection uConn = null; try { - in = configURL.openStream(); - props.load(in); - } catch (Exception e) { - String errMsg = - "Could not read configuration file from URL [" + configURL + "]."; - addError(new ErrorItem(errMsg, e)); - getLogger(repository).error(errMsg, e); + uConn = configURL.openConnection(); + uConn.setUseCaches(false); + istream = uConn.getInputStream(); + props.load(istream); + } + catch (Exception e) { + if (e instanceof InterruptedIOException || e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } + LogLog.error("Could not read configuration file from URL [" + configURL + + "].", e); + LogLog.error("Ignoring configuration file [" + configURL +"]."); return; - } finally { - if (in != null) { + } + finally { + if (istream != null) { try { - in.close(); - } catch(IOException ignored) { + istream.close(); + } catch(InterruptedIOException ignore) { + Thread.currentThread().interrupt(); + } catch(IOException ignore) { + } catch(RuntimeException ignore) { } } } - - doConfigure(props, repository); + doConfigure(props, hierarchy); } - /** - * Read configuration options from input stream configStream. - * @since 1.3 - * @param configStream - * @param repository - */ - public void doConfigure(InputStream configStream, - LoggerRepository repository) { - Properties props = new Properties(); - getLogger(repository).debug( - "Reading configuration from input stream"); - - try { - props.load(configStream); - } catch (java.io.IOException e) { - String errMsg = - "Could not read configuration file from input stream."; - addError(new ErrorItem(errMsg, e)); - getLogger(repository).error(errMsg, e); - return; - } - - doConfigure(props, repository); - } // -------------------------------------------------------------------------- // Internal stuff @@ -548,77 +596,107 @@ public void doConfigure(InputStream configStream, @see #parseCatsAndRenderers */ - protected void configureLoggerFactory(Properties props, LoggerRepository repository) { - String factoryClassName = - OptionConverter.findAndSubst(LOGGER_FACTORY_KEY, props); - - if (factoryClassName != null) { - loggerFactory = - (LoggerFactory) OptionConverter.instantiateByClassName( - factoryClassName, LoggerFactory.class, loggerFactory); - PropertySetter setter = new PropertySetter(loggerFactory); - setter.setLoggerRepository(repository); - setter.setProperties(props, FACTORY_PREFIX + "."); + protected void configureLoggerFactory(Properties props) { + String factoryClassName = OptionConverter.findAndSubst(LOGGER_FACTORY_KEY, + props); + if(factoryClassName != null) { + LogLog.debug("Setting category factory to ["+factoryClassName+"]."); + loggerFactory = (LoggerFactory) + OptionConverter.instantiateByClassName(factoryClassName, + LoggerFactory.class, + loggerFactory); + PropertySetter.setProperties(loggerFactory, props, FACTORY_PREFIX + "."); } } - void configureRootCategory(Properties props, LoggerRepository repository) { + /* + void configureOptionHandler(OptionHandler oh, String prefix, + Properties props) { + String[] options = oh.getOptionStrings(); + if(options == null) + return; + + String value; + for(int i = 0; i < options.length; i++) { + value = OptionConverter.findAndSubst(prefix + options[i], props); + LogLog.debug( + "Option " + options[i] + "=[" + (value == null? "N/A" : value)+"]."); + // Some option handlers assume that null value are not passed to them. + // So don't remove this check + if(value != null) { + oh.setOption(options[i], value); + } + } + oh.activateOptions(); + } + */ + + + void configureRootCategory(Properties props, LoggerRepository hierarchy) { String effectiveFrefix = ROOT_LOGGER_PREFIX; String value = OptionConverter.findAndSubst(ROOT_LOGGER_PREFIX, props); - if (value == null) { + if(value == null) { value = OptionConverter.findAndSubst(ROOT_CATEGORY_PREFIX, props); effectiveFrefix = ROOT_CATEGORY_PREFIX; } - if (value == null) { - getLogger(repository).debug( - "Could not find root logger information. Is this OK?"); + if(value == null) { + LogLog.debug("Could not find root logger information. Is this OK?"); } else { - Logger root = repository.getRootLogger(); - - synchronized (root) { - parseCategory( - repository, props, root, effectiveFrefix, INTERNAL_ROOT_NAME, value); + Logger root = hierarchy.getRootLogger(); + synchronized(root) { + parseCategory(props, root, effectiveFrefix, INTERNAL_ROOT_NAME, value); } } } + /** Parse non-root elements, such non-root categories and renderers. */ - protected void parseCatsAndRenderers( - Properties props, LoggerRepository repository) { + protected + void parseCatsAndRenderers(Properties props, LoggerRepository hierarchy) { Enumeration enumeration = props.propertyNames(); - - while (enumeration.hasMoreElements()) { + 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)) { + loggerName = key.substring(CATEGORY_PREFIX.length()); + } else if(key.startsWith(LOGGER_PREFIX)) { + loggerName = key.substring(LOGGER_PREFIX.length()); + } + String value = OptionConverter.findAndSubst(key, props); + Logger logger = hierarchy.getLogger(loggerName, loggerFactory); + synchronized(logger) { + parseCategory(props, logger, key, loggerName, value); + parseAdditivityForLogger(props, logger, loggerName); + } + } else if(key.startsWith(RENDERER_PREFIX)) { + String renderedClass = key.substring(RENDERER_PREFIX.length()); + String renderingClass = OptionConverter.findAndSubst(key, props); + if(hierarchy instanceof RendererSupport) { + RendererMap.addRenderer((RendererSupport) hierarchy, renderedClass, + renderingClass); + } + } else if (key.equals(THROWABLE_RENDERER_PREFIX)) { + if (hierarchy instanceof ThrowableRendererSupport) { + ThrowableRenderer tr = (ThrowableRenderer) + OptionConverter.instantiateByKey(props, + THROWABLE_RENDERER_PREFIX, + org.apache.log4j.spi.ThrowableRenderer.class, + null); + if(tr == null) { + LogLog.error( + "Could not instantiate throwableRenderer."); + } else { + PropertySetter setter = new PropertySetter(tr); + setter.setProperties(props, THROWABLE_RENDERER_PREFIX + "."); + ((ThrowableRendererSupport) hierarchy).setThrowableRenderer(tr); - if (key.startsWith(CATEGORY_PREFIX) || key.startsWith(LOGGER_PREFIX)) { - String loggerName = null; - - if (key.startsWith(CATEGORY_PREFIX)) { - loggerName = key.substring(CATEGORY_PREFIX.length()); - } else if (key.startsWith(LOGGER_PREFIX)) { - loggerName = key.substring(LOGGER_PREFIX.length()); - } - - String value = OptionConverter.findAndSubst(key, props); - Logger logger = repository.getLogger(loggerName, loggerFactory); - - synchronized (logger) { - parseCategory(repository, props, logger, key, loggerName, value); - parseAdditivityForLogger(repository, props, logger, loggerName); - } - } else if (key.startsWith(RENDERER_PREFIX)) { - String renderedClass = key.substring(RENDERER_PREFIX.length()); - String renderingClass = OptionConverter.findAndSubst(key, props); - - if (repository instanceof RendererSupport) { - RendererSupport rs = (RendererSupport) repository; - RendererMap rm = rs.getRendererMap(); - rm.addRenderer(renderedClass, renderingClass); - } + } + } } } } @@ -626,19 +704,16 @@ protected void parseCatsAndRenderers( /** Parse the additivity option for a non-root category. */ - void parseAdditivityForLogger( - LoggerRepository repository, Properties props, Logger cat, - String loggerName) { - String value = - OptionConverter.findAndSubst(ADDITIVITY_PREFIX + loggerName, props); - getLogger(repository).debug( - "Handling " + ADDITIVITY_PREFIX + loggerName + "=[" + value + "]"); - + void parseAdditivityForLogger(Properties props, Logger cat, + String loggerName) { + String value = OptionConverter.findAndSubst(ADDITIVITY_PREFIX + loggerName, + props); + LogLog.debug("Handling "+ADDITIVITY_PREFIX + loggerName+"=["+value+"]"); // touch additivity only if necessary - if ((value != null) && (!value.equals(""))) { + if((value != null) && (!value.equals(""))) { boolean additivity = OptionConverter.toBoolean(value, true); - getLogger(repository).debug( - "Setting additivity for \"" + loggerName + "\" to " + additivity); + LogLog.debug("Setting additivity for \""+loggerName+"\" to "+ + additivity); cat.setAdditivity(additivity); } } @@ -646,43 +721,40 @@ void parseAdditivityForLogger( /** This method must work for the root category as well. */ - void parseCategory( - LoggerRepository repository, Properties props, Logger logger, - String optionKey, String loggerName, String value) { - getLogger(repository).debug( - "Parsing for [{}] with value=[{}].", loggerName, value); + void parseCategory(Properties props, Logger logger, String optionKey, + String loggerName, String value) { + LogLog.debug("Parsing for [" +loggerName +"] with value=[" + value+"]."); // We must skip over ',' but not white space StringTokenizer st = new StringTokenizer(value, ","); // If value is not in the form ", appender.." or "", then we should set // the level of the loggeregory. - if (!(value.startsWith(",") || value.equals(""))) { + + if(!(value.startsWith(",") || value.equals(""))) { + // just to be on the safe side... - if (!st.hasMoreTokens()) { + if(!st.hasMoreTokens()) { return; - } + } - String levelStr = st.nextToken().trim(); - getLogger(repository).debug("Level token is [{}].", levelStr); + String levelStr = st.nextToken(); + LogLog.debug("Level token is [" + levelStr + "]."); // 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 ( - Configurator.INHERITED.equalsIgnoreCase(levelStr) - || Configurator.NULL.equalsIgnoreCase(levelStr)) { - if (loggerName.equals(INTERNAL_ROOT_NAME)) { - getLogger(repository).warn("The root logger cannot be set to null."); - } else { - 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.DEBUG)); + logger.setLevel(OptionConverter.toLevel(levelStr, Level.DEBUG)); } - - getLogger(repository).debug( - "Category {} set to {}.", loggerName, logger.getLevel()); + LogLog.debug("Category " + loggerName + " set to " + logger.getLevel()); } // Begin by removing all existing appenders. @@ -690,107 +762,242 @@ void parseCategory( Appender appender; String appenderName; - - while (st.hasMoreTokens()) { + while(st.hasMoreTokens()) { appenderName = st.nextToken().trim(); - - if ((appenderName == null) || appenderName.equals(",")) { + if(appenderName == null || appenderName.equals(",")) { continue; - } - - getLogger(repository).debug( - "Parsing appender named \"{}\".", appenderName); - appender = parseAppender(repository, props, appenderName); - - if (appender != null) { - logger.addAppender(appender); + } + LogLog.debug("Parsing appender named \"" + appenderName +"\"."); + appender = parseAppender(props, appenderName); + if(appender != null) { + logger.addAppender(appender); } } } - Appender parseAppender( - LoggerRepository repository, Properties props, String appenderName) { + Appender parseAppender(Properties props, String appenderName) { Appender appender = registryGet(appenderName); - - if ((appender != null)) { - getLogger(repository).debug( - "Appender \"{}\" was already parsed.", appenderName); - + if((appender != null)) { + LogLog.debug("Appender \"" + appenderName + "\" was already parsed."); return appender; } - // Appender was not previously initialized. String prefix = APPENDER_PREFIX + appenderName; String layoutPrefix = prefix + ".layout"; - appender = - (Appender) OptionConverter.instantiateByKey( - props, prefix, org.apache.log4j.Appender.class, null); - - if (appender == null) { - String errMsg = - "Could not instantiate appender named \"" + appenderName + "\"."; - addError(new ErrorItem(errMsg)); - getLogger(repository).error(errMsg); + appender = (Appender) OptionConverter.instantiateByKey(props, prefix, + org.apache.log4j.Appender.class, + null); + if(appender == null) { + LogLog.error( + "Could not instantiate appender named \"" + appenderName+"\"."); return null; } - appender.setName(appenderName); - appender.setLoggerRepository(repository); - if (appender instanceof OptionHandler) { - String layoutClassName = - OptionConverter.findAndSubst(layoutPrefix, props); - - // if there are layout related directives, we process these now - if (layoutClassName != null) { - // Trim layoutClassName to avoid trailing spaces that cause problems. - Layout layout = - (Layout) OptionConverter.instantiateByClassName( - layoutClassName.trim(), Layout.class, null); - - if (layout != null) { - layout.setLoggerRepository(repository); - appender.setLayout(layout); - getLogger(repository).debug( - "Parsing layout options for \"" + appenderName + "\"."); - - PropertySetter layoutPS = new PropertySetter(layout); - layoutPS.setLoggerRepository(repository); - layoutPS.setProperties(props, layoutPrefix + "."); - - activateOptions(layout); - getLogger(repository).debug( - "End of parsing for \"" + appenderName + "\"."); - } - } - PropertySetter appenderPS = new PropertySetter(appender); - appenderPS.setLoggerRepository(repository); - appenderPS.setProperties(props, prefix + "."); - activateOptions(appender); - getLogger(repository).debug("Parsed \"" + appenderName + "\" options."); + if(appender instanceof OptionHandler) { + if(appender.requiresLayout()) { + Layout layout = (Layout) OptionConverter.instantiateByKey(props, + layoutPrefix, + Layout.class, + null); + if(layout != null) { + appender.setLayout(layout); + LogLog.debug("Parsing layout options for \"" + appenderName +"\"."); + //configureOptionHandler(layout, layoutPrefix + ".", props); + PropertySetter.setProperties(layout, props, layoutPrefix + "."); + LogLog.debug("End of parsing for \"" + appenderName +"\"."); + } + } + final String errorHandlerPrefix = prefix + ".errorhandler"; + String errorHandlerClass = OptionConverter.findAndSubst(errorHandlerPrefix, props); + if (errorHandlerClass != null) { + ErrorHandler eh = (ErrorHandler) OptionConverter.instantiateByKey(props, + errorHandlerPrefix, + ErrorHandler.class, + null); + if (eh != null) { + appender.setErrorHandler(eh); + LogLog.debug("Parsing errorhandler options for \"" + appenderName +"\"."); + parseErrorHandler(eh, errorHandlerPrefix, props, repository); + final Properties edited = new Properties(); + final String[] keys = new String[] { + errorHandlerPrefix + "." + ROOT_REF, + errorHandlerPrefix + "." + LOGGER_REF, + errorHandlerPrefix + "." + APPENDER_REF_TAG + }; + for(Iterator iter = props.entrySet().iterator();iter.hasNext();) { + Map.Entry entry = (Map.Entry) iter.next(); + int i = 0; + for(; i < keys.length; i++) { + if(keys[i].equals(entry.getKey())) { + break; + } + } + if (i == keys.length) { + edited.put(entry.getKey(), entry.getValue()); + } + } + PropertySetter.setProperties(eh, edited, errorHandlerPrefix + "."); + LogLog.debug("End of errorhandler parsing for \"" + appenderName +"\"."); + } + + } + //configureOptionHandler((OptionHandler) appender, prefix + ".", props); + PropertySetter.setProperties(appender, props, prefix + "."); + LogLog.debug("Parsed \"" + appenderName +"\" options."); } - + parseAppenderFilters(props, appenderName, appender); registryPut(appender); - return appender; } + + private void parseErrorHandler( + final ErrorHandler eh, + final String errorHandlerPrefix, + final Properties props, + final LoggerRepository hierarchy) { + boolean rootRef = OptionConverter.toBoolean( + OptionConverter.findAndSubst(errorHandlerPrefix + ROOT_REF, props), false); + if (rootRef) { + eh.setLogger(hierarchy.getRootLogger()); + } + String loggerName = OptionConverter.findAndSubst(errorHandlerPrefix + LOGGER_REF , props); + if (loggerName != null) { + Logger logger = (loggerFactory == null) ? hierarchy.getLogger(loggerName) + : hierarchy.getLogger(loggerName, loggerFactory); + eh.setLogger(logger); + } + String appenderName = OptionConverter.findAndSubst(errorHandlerPrefix + APPENDER_REF_TAG, props); + if (appenderName != null) { + Appender backup = parseAppender(props, appenderName); + if (backup != null) { + eh.setBackupAppender(backup); + } + } + } + + + void parseAppenderFilters(Properties props, String appenderName, Appender appender) { + // extract filters and filter options from props into a hashtable mapping + // the property name defining the filter class to a list of pre-parsed + // name-value pairs associated to that filter + final String filterPrefix = APPENDER_PREFIX + appenderName + ".filter."; + int fIdx = filterPrefix.length(); + Hashtable filters = new Hashtable(); + Enumeration e = props.keys(); + String name = ""; + while (e.hasMoreElements()) { + String key = (String) e.nextElement(); + if (key.startsWith(filterPrefix)) { + int dotIdx = key.indexOf('.', fIdx); + String filterKey = key; + if (dotIdx != -1) { + filterKey = key.substring(0, dotIdx); + name = key.substring(dotIdx+1); + } + Vector filterOpts = (Vector) filters.get(filterKey); + if (filterOpts == null) { + filterOpts = new Vector(); + filters.put(filterKey, filterOpts); + } + if (dotIdx != -1) { + String value = OptionConverter.findAndSubst(key, props); + filterOpts.add(new NameValue(name, value)); + } + } + } - void activateOptions(Object obj) { - if (obj instanceof OptionHandler) { - ((OptionHandler) obj).activateOptions(); + // sort filters by IDs, insantiate filters, set filter options, + // add filters to the appender + Enumeration g = new SortedKeyEnumeration(filters); + while (g.hasMoreElements()) { + String key = (String) g.nextElement(); + String clazz = props.getProperty(key); + if (clazz != null) { + LogLog.debug("Filter key: ["+key+"] class: ["+props.getProperty(key) +"] props: "+filters.get(key)); + Filter filter = (Filter) OptionConverter.instantiateByClassName(clazz, Filter.class, null); + if (filter != null) { + PropertySetter propSetter = new PropertySetter(filter); + Vector v = (Vector)filters.get(key); + Enumeration filterProps = v.elements(); + while (filterProps.hasMoreElements()) { + NameValue kv = (NameValue)filterProps.nextElement(); + propSetter.setProperty(kv.key, kv.value); + } + propSetter.activate(); + LogLog.debug("Adding filter of type ["+filter.getClass() + +"] to appender named ["+appender.getName()+"]."); + appender.addFilter(filter); + } + } else { + LogLog.warn("Missing class definition for filter: ["+key+"]"); + } } } - void registryPut(Appender appender) { + + void registryPut(Appender appender) { registry.put(appender.getName(), appender); } Appender registryGet(String name) { return (Appender) registry.get(name); } +} + +class PropertyWatchdog extends FileWatchdog { + + PropertyWatchdog(String filename) { + super(filename); + } + + /** + Call {@link PropertyConfigurator#configure(String)} with the + filename to reconfigure log4j. */ + public + void doOnChange() { + new PropertyConfigurator().doConfigure(filename, + LogManager.getLoggerRepository()); + } +} + +class NameValue { + String key, value; + public NameValue(String key, String value) { + this.key = key; + this.value = value; + } + public String toString() { + return key + "=" + value; + } +} + +class SortedKeyEnumeration implements Enumeration { + + private Enumeration e; + + public SortedKeyEnumeration(Hashtable ht) { + Enumeration f = ht.keys(); + Vector keys = new Vector(ht.size()); + for (int i, last = 0; f.hasMoreElements(); ++last) { + String key = (String) f.nextElement(); + for (i = 0; i < last; ++i) { + String s = (String) keys.get(i); + if (key.compareTo(s) <= 0) { + break; + } + } + keys.add(i, key); + } + e = keys.elements(); + } + + public boolean hasMoreElements() { + return e.hasMoreElements(); + } - public List getErrorList() { - return errorList; + public Object nextElement() { + return e.nextElement(); } } diff --git a/src/main/java/org/apache/log4j/ProvisionNode.java b/src/main/java/org/apache/log4j/ProvisionNode.java index 0a4174fb1f..f1126822a1 100644 --- a/src/main/java/org/apache/log4j/ProvisionNode.java +++ b/src/main/java/org/apache/log4j/ProvisionNode.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -18,8 +19,9 @@ import java.util.Vector; - class ProvisionNode extends Vector { + private static final long serialVersionUID = -4479121426311014469L; + ProvisionNode(Logger logger) { super(); this.addElement(logger); diff --git a/src/main/java/org/apache/log4j/RollingFileAppender.java b/src/main/java/org/apache/log4j/RollingFileAppender.java index 22f305d8e1..9cfacc6b75 100644 --- a/src/main/java/org/apache/log4j/RollingFileAppender.java +++ b/src/main/java/org/apache/log4j/RollingFileAppender.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -21,6 +22,8 @@ import java.io.IOException; import java.io.Writer; import java.io.File; +import java.io.InterruptedIOException; + import org.apache.log4j.helpers.OptionConverter; import org.apache.log4j.helpers.LogLog; import org.apache.log4j.helpers.CountingQuietWriter; @@ -29,12 +32,15 @@ /** RollingFileAppender extends FileAppender to backup the log files when they reach a certain size. + + The log4j extras companion includes alternatives which should be considered + for new deployments and which are discussed in the documentation + for org.apache.log4j.rolling.RollingFileAppender. + @author Heinz Richter @author Ceki Gülcü - @deprecated Since log4j 1.3, use org.apache.log4j.rolling.RollingFileAppender instead. - */ public class RollingFileAppender extends FileAppender { @@ -48,6 +54,8 @@ public class RollingFileAppender extends FileAppender { */ protected int maxBackupIndex = 1; + private long nextRollover = 0; + /** The default constructor simply calls its {@link FileAppender#FileAppender parents constructor}. */ @@ -121,27 +129,34 @@ void rollOver() { File file; if (qw != null) { - LogLog.debug("rolling over count=" + ((CountingQuietWriter) qw).getCount()); + long size = ((CountingQuietWriter) qw).getCount(); + LogLog.debug("rolling over count=" + size); + // if operation fails, do not roll again until + // maxFileSize more bytes are written + nextRollover = size + maxFileSize; } LogLog.debug("maxBackupIndex="+maxBackupIndex); + boolean renameSucceeded = true; // If maxBackups <= 0, then there is no file renaming to be done. if(maxBackupIndex > 0) { // Delete the oldest file, to keep Windows happy. file = new File(fileName + '.' + maxBackupIndex); - if (file.exists()) - file.delete(); + if (file.exists()) { + renameSucceeded = file.delete(); + } // Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3, 2} - for (int i = maxBackupIndex - 1; i >= 1; i--) { + for (int i = maxBackupIndex - 1; i >= 1 && renameSucceeded; i--) { file = new File(fileName + "." + i); if (file.exists()) { target = new File(fileName + '.' + (i + 1)); LogLog.debug("Renaming file " + file + " to " + target); - file.renameTo(target); + renameSucceeded = file.renameTo(target); } } + if(renameSucceeded) { // Rename fileName to fileName.1 target = new File(fileName + "." + 1); @@ -149,16 +164,40 @@ void rollOver() { file = new File(fileName); LogLog.debug("Renaming file " + file + " to " + target); - file.renameTo(target); + renameSucceeded = file.renameTo(target); + // + // if file rename failed, reopen file with append = true + // + if (!renameSucceeded) { + try { + this.setFile(fileName, true, bufferedIO, bufferSize); + } + catch(IOException e) { + if (e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.error("setFile("+fileName+", true) call failed.", e); + } + } + } } + // + // if all renames were successful, then + // + if (renameSucceeded) { try { // This will also close the file. This is OK since multiple // close operations are safe. this.setFile(fileName, false, bufferedIO, bufferSize); + nextRollover = 0; } catch(IOException e) { - LogLog.error("setFile("+fileName+", false) call failed.", e); + if (e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.error("setFile("+fileName+", false) call failed.", e); + } } } @@ -236,8 +275,11 @@ void setQWForFiles(Writer writer) { protected void subAppend(LoggingEvent event) { super.subAppend(event); - if((fileName != null) && - ((CountingQuietWriter) qw).getCount() >= maxFileSize) - this.rollOver(); + if(fileName != null && qw != null) { + long size = ((CountingQuietWriter) qw).getCount(); + if (size >= maxFileSize && size >= nextRollover) { + rollOver(); + } + } } } diff --git a/src/main/java/org/apache/log4j/SimpleLayout.java b/src/main/java/org/apache/log4j/SimpleLayout.java index a38f4dd5df..5699661ba6 100644 --- a/src/main/java/org/apache/log4j/SimpleLayout.java +++ b/src/main/java/org/apache/log4j/SimpleLayout.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -18,9 +19,6 @@ import org.apache.log4j.spi.LoggingEvent; -import java.io.Writer; - - /** SimpleLayout consists of the level of the log statement, followed by " - " and then the log message itself. For example, @@ -32,42 +30,49 @@

    @author Ceki Gülcü @since version 0.7.0 - @deprecated since 1.3

    {@link PatternLayout} offers a much more powerful alternative. */ public class SimpleLayout extends Layout { - /** - * Result of previous format request. Not reliable if not - * layout is not externally synchronized. - * @deprecated since 1.3 - */ + StringBuffer sbuf = new StringBuffer(128); public SimpleLayout() { } - public void activateOptions() { + public + void activateOptions() { } - + /** - Writes the log statement in a format consisting of the - level, followed by " - " and then the - message. For example,

     INFO - "A message"
    -	 
    + Returns the log statement in a format consisting of the + level, followed by " - " and then the + message. For example,
     INFO - "A message"
    +     
    + +

    The category parameter is ignored. +

    + @return A byte array in SimpleLayout format. + */ + public + String format(LoggingEvent event) { -

    The category parameter is ignored. -

    - @param event The LoggingEvent to format and write - */ - public String format(final LoggingEvent event) { - StringBuffer sb = new StringBuffer(event.getLevel().toString()); - sb.append(" - "); - sb.append(event.getRenderedMessage()); - sb.append(LINE_SEP); - String s = sb.toString(); sbuf.setLength(0); - sbuf.append(s); - return s; - } + sbuf.append(event.getLevel().toString()); + sbuf.append(" - "); + sbuf.append(event.getRenderedMessage()); + sbuf.append(LINE_SEP); + return sbuf.toString(); + } + +/** + The SimpleLayout does not handle the throwable contained within + {@link LoggingEvent LoggingEvents}. Thus, it returns + true. + + @since version 0.8.4 */ + public + boolean ignoresThrowable() { + return true; + } } diff --git a/src/main/java/org/apache/log4j/TTCCLayout.java b/src/main/java/org/apache/log4j/TTCCLayout.java index e223d64f2a..3b0e98f967 100644 --- a/src/main/java/org/apache/log4j/TTCCLayout.java +++ b/src/main/java/org/apache/log4j/TTCCLayout.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,13 +17,12 @@ // Contributors: Christopher Williams // Mathias Bogaert + package org.apache.log4j; -import org.apache.log4j.helpers.Constants; +import org.apache.log4j.helpers.DateLayout; import org.apache.log4j.spi.LoggingEvent; - - /** TTCC layout format consists of time, thread, category and nested diagnostic context information, hence the name. @@ -60,53 +60,66 @@

    The fifth field (just before the '-') is the nested diagnostic first two statements. The text after the '-' is the message of the statement. +

    WARNING Do not use the same TTCCLayout instance from + within different appenders. The TTCCLayout is not thread safe when + used in his way. However, it is perfectly safe to use a TTCCLayout + instance from just one appender. +

    {@link PatternLayout} offers a much more flexible alternative. @author Ceki Gülcü @author Heinz Richter - @deprecated Please use {@link PatternLayout} instead. + */ -public class TTCCLayout extends org.apache.log4j.helpers.DateLayout { +public class TTCCLayout extends DateLayout { + // Internal representation of options - private boolean threadPrinting = true; + private boolean threadPrinting = true; private boolean categoryPrefixing = true; - private boolean contextPrinting = true; - protected final StringBuffer buf = new StringBuffer(64); + private boolean contextPrinting = true; + + + protected final StringBuffer buf = new StringBuffer(256); + /** - * Instantiate a TTCCLayout object with in the ISO8601 format as the date - * formatter. - * */ + Instantiate a TTCCLayout object with {@link + org.apache.log4j.helpers.RelativeTimeDateFormat} as the date + formatter in the local time zone. + + @since 0.7.5 */ public TTCCLayout() { - this.setDateFormat(Constants.ISO8601_FORMAT); + this.setDateFormat(RELATIVE_TIME_DATE_FORMAT, null); } + /** Instantiate a TTCCLayout object using the local time zone. The DateFormat used will depend on the dateFormatType. -

    This constructor just calls the {@link #setDateFormat} method. - */ +

    This constructor just calls the {@link + DateLayout#setDateFormat} method. + + */ public TTCCLayout(String dateFormatType) { this.setDateFormat(dateFormatType); } - public void activateOptions() { - } - /** The ThreadPrinting option specifies whether the name of the current thread is part of log output or not. This is true by default. */ - public void setThreadPrinting(boolean threadPrinting) { + public + void setThreadPrinting(boolean threadPrinting) { this.threadPrinting = threadPrinting; } /** Returns value of the ThreadPrinting option. */ - public boolean getThreadPrinting() { + public + boolean getThreadPrinting() { return threadPrinting; } @@ -114,14 +127,16 @@ public boolean getThreadPrinting() { The CategoryPrefixing option specifies whether {@link Category} name is part of log output or not. This is true by default. */ - public void setCategoryPrefixing(boolean categoryPrefixing) { + public + void setCategoryPrefixing(boolean categoryPrefixing) { this.categoryPrefixing = categoryPrefixing; } /** Returns value of the CategoryPrefixing option. */ - public boolean getCategoryPrefixing() { + public + boolean getCategoryPrefixing() { return categoryPrefixing; } @@ -130,18 +145,19 @@ public boolean getCategoryPrefixing() { the nested context information belonging to the current thread. This is true by default. */ - public void setContextPrinting(boolean contextPrinting) { + public + void setContextPrinting(boolean contextPrinting) { this.contextPrinting = contextPrinting; } /** Returns value of the ContextPrinting option. */ - public boolean getContextPrinting() { + public + boolean getContextPrinting() { return contextPrinting; } - /** In addition to the level of the statement and message, the returned byte array includes time, thread, category and {@link NDC} @@ -149,37 +165,53 @@ public boolean getContextPrinting() {

    Time, thread, category and diagnostic context are printed depending on options. + + @param event The event to format + */ - public String format(final LoggingEvent event) { + public + String format(LoggingEvent event) { + + // Reset buf buf.setLength(0); + dateFormat(buf, event); - if (this.threadPrinting) { + if(this.threadPrinting) { buf.append('['); buf.append(event.getThreadName()); buf.append("] "); } - buf.append(event.getLevel().toString()); buf.append(' '); - if (this.categoryPrefixing) { + if(this.categoryPrefixing) { buf.append(event.getLoggerName()); buf.append(' '); } - if (this.contextPrinting) { - String ndc = event.getNDC(); + if(this.contextPrinting) { + String ndc = event.getNDC(); - if (ndc != null) { - buf.append(ndc); - buf.append(' '); + if(ndc != null) { + buf.append(ndc); + buf.append(' '); } } - buf.append("- "); buf.append(event.getRenderedMessage()); buf.append(LINE_SEP); return buf.toString(); } + + /** + The TTCCLayout does not handle the throwable contained within + {@link LoggingEvent LoggingEvents}. Thus, it returns + true. + + @since version 0.8.4 */ + public + boolean ignoresThrowable() { + return true; + } } diff --git a/src/main/java/org/apache/log4j/ULogger.java b/src/main/java/org/apache/log4j/ULogger.java deleted file mode 100644 index 83a6bb8a3d..0000000000 --- a/src/main/java/org/apache/log4j/ULogger.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j; - - -/** - * A proxy for org.slf4j.ULogger. In slf4j implementing builds, this - * interface will extend org.slf4j.ULogger and add no additional methods. - * - * @author Ceki Gülcü - * @author Curt Arnold - */ - public interface ULogger { - - - /** - * Is the logger instance enabled for the DEBUG level? - * @return true if debug is enabled. - */ - boolean isDebugEnabled(); - - /** - * Log a message object with the DEBUG level. - * @param msg - the message object to be logged - */ - void debug(Object msg); - - - /** - * Log a parameterized message object at the DEBUG level. - * - *

    This form is useful in avoiding the superflous object creation - * problem when invoking this method while it is disabled. - *

    - * @param parameterizedMsg - the parameterized message object - * @param param1 - the parameter - */ - void debug(Object parameterizedMsg, Object param1); - - /** - * Log a parameterized message object at the DEBUG level. - * - *

    This form is useful in avoiding the superflous object creation - * problem when invoking this method while it is disabled. - *

    - * @param parameterizedMsg - the parameterized message object - * @param param1 - the first parameter - * @param param2 - the second parameter - */ - void debug(String parameterizedMsg, Object param1, Object param2); - /** - * Log a message object with the DEBUG level including the - * stack trace of the {@link Throwable}t passed as parameter. - * - * - * @param msg the message object to log. - * @param t the exception to log, including its stack trace. - */ - void debug(Object msg, Throwable t); - - - /** - * Is the logger instance enabled for the INFO level? - * @return true if debug is enabled. - */ - boolean isInfoEnabled(); - /** - * Log a message object with the INFO level. - * @param msg - the message object to be logged - */ - void info(Object msg); - /** - * Log a parameterized message object at the INFO level. - * - *

    This form is useful in avoiding the superflous object creation - * problem when invoking this method while it is disabled. - *

    - * @param parameterizedMsg - the parameterized message object - * @param param1 - the parameter - */ - void info(Object parameterizedMsg, Object param1); - /** - * Log a parameterized message object at the INFO level. - * - *

    This form is useful in avoiding the superflous object creation - * problem when invoking this method while it is disabled. - *

    - * @param parameterizedMsg - the parameterized message object - * @param param1 - the first parameter - * @param param2 - the second parameter - */ - void info(String parameterizedMsg, Object param1, Object param2); - /** - * Log a message object with the INFO level including the - * stack trace of the {@link Throwable}t passed as parameter. - * - * - * @param msg the message object to log. - * @param t the exception to log, including its stack trace. - */ - void info(Object msg, Throwable t); - - - /** - * Is the logger instance enabled for the WARN level? - * @return true if debug is enabled. - */ - boolean isWarnEnabled(); - /** - * Log a message object with the WARN level. - * @param msg - the message object to be logged - */ - void warn(Object msg); - /** - * Log a parameterized message object at the WARN level. - * - *

    This form is useful in avoiding the superflous object creation - * problem when invoking this method while it is disabled. - *

    - * @param parameterizedMsg - the parameterized message object - * @param param1 - the parameter - */ - void warn(Object parameterizedMsg, Object param1); - /** - * Log a parameterized message object at the WARN level. - * - *

    This form is useful in avoiding the superflous object creation - * problem when invoking this method while it is disabled. - *

    - * @param parameterizedMsg - the parameterized message object - * @param param1 - the first parameter - * @param param2 - the second parameter - */ - void warn(String parameterizedMsg, Object param1, Object param2); - /** - * Log a message object with the WARN level including the - * stack trace of the {@link Throwable}t passed as parameter. - * - * - * @param msg the message object to log. - * @param t the exception to log, including its stack trace. - */ - void warn(Object msg, Throwable t); - - - /** - * Is the logger instance enabled for the ERROR level? - * @return true if debug is enabled. - */ - boolean isErrorEnabled(); - /** - * Log a message object with the ERROR level. - * @param msg - the message object to be logged - */ - void error(Object msg); - /** - * Log a parameterized message object at the ERROR level. - * - *

    This form is useful in avoiding the superflous object creation - * problem when invoking this method while it is disabled. - *

    - * @param parameterizedMsg - the parameterized message object - * @param param1 - the parameter - */ - void error(Object parameterizedMsg, Object param1); - /** - * Log a parameterized message object at the ERROR level. - * - *

    This form is useful in avoiding the superflous object creation - * problem when invoking this method while it is disabled. - *

    - * @param parameterizedMsg - the parameterized message object - * @param param1 - the first parameter - * @param param2 - the second parameter - */ - void error(String parameterizedMsg, Object param1, Object param2); - - /** - * Log a message object with the ERROR level including the - * stack trace of the {@link Throwable}t passed as parameter. - * - * - * @param msg the message object to log. - * @param t the exception to log, including its stack trace. - */ - void error(Object msg, Throwable t); - -} diff --git a/src/main/java/org/apache/log4j/WriterAppender.java b/src/main/java/org/apache/log4j/WriterAppender.java index 9773e794f2..1c93cc256e 100644 --- a/src/main/java/org/apache/log4j/WriterAppender.java +++ b/src/main/java/org/apache/log4j/WriterAppender.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,30 +17,33 @@ package org.apache.log4j; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.ErrorHandler; - import java.io.IOException; +import java.io.InterruptedIOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; + +import org.apache.log4j.helpers.LogLog; import org.apache.log4j.helpers.QuietWriter; +import org.apache.log4j.spi.ErrorHandler; +import org.apache.log4j.spi.LoggingEvent; // Contibutors: Jens Uwe Pipka // Ben Sandee /** - * WriterAppender appends log events to a {@link java.io.Writer} or an - * {@link java.io.OutputStream} depending on the user's choice. - * - * @author Ceki Gülcü - * @since 1.1 - * */ + WriterAppender appends log events to a {@link java.io.Writer} or an + {@link java.io.OutputStream} depending on the user's choice. + + @author Ceki Gülcü + @since 1.1 */ public class WriterAppender extends AppenderSkeleton { - + + /** Immediate flush means that the underlying writer or output stream - will be flushed at the end of each append operation. Immediate + will be flushed at the end of each append operation unless shouldFlush() + is overridden. Immediate flush is slower but ensures that each append request is actually written. If immediateFlush is set to false, then there is a good chance that the last few @@ -60,43 +64,37 @@ public class WriterAppender extends AppenderSkeleton { protected String encoding; /** - * This is the {@link QuietWriter quietWriter} where we will write to. + This is the {@link QuietWriter quietWriter} where we will write + to. */ protected QuietWriter qw; + /** - * The default constructor does nothing. - * */ - public WriterAppender() { - super(false); + This default constructor does nothing. */ + public + WriterAppender() { } /** - * Instantiate a WriterAppender and set the output destination to a new - * {@link OutputStreamWriter} initialized with os as its - * {@link OutputStream}. - * - * @deprecated This constructor will be removed with no replacement in - * future log4j versions. - * */ - public WriterAppender(Layout layout, OutputStream os) { + Instantiate a WriterAppender and set the output destination to a + new {@link OutputStreamWriter} initialized with os + as its {@link OutputStream}. */ + public + WriterAppender(Layout layout, OutputStream os) { this(layout, new OutputStreamWriter(os)); } /** - * Instantiate a WriterAppender and set the output destination to - * writer. - *

    - * The writer must have been previously opened by the user. - * - * @deprecated This constructor will be removed with no replacement in - * future log4j versions - * */ - public WriterAppender(Layout layout, Writer writer) { - super(false); + Instantiate a WriterAppender and set the output destination to + writer. + +

    The writer must have been previously opened by + the user. */ + public + WriterAppender(Layout layout, Writer writer) { this.layout = layout; this.setWriter(writer); - this.activateOptions(); } /** @@ -113,40 +111,27 @@ public WriterAppender(Layout layout, Writer writer) { be recorded on disk when the application exits. This is a high price to pay even for a 20% performance gain. */ - public void setImmediateFlush(boolean value) { + public + void setImmediateFlush(boolean value) { immediateFlush = value; } /** Returns value of the ImmediateFlush option. */ - public boolean getImmediateFlush() { + public + boolean getImmediateFlush() { return immediateFlush; } /** - * Checks that requires parameters are set and if everything is in order, - * activates this appender. + Does nothing. */ - public void activateOptions() { - int errors = 0; - if (this.layout == null) { - getLogger().error( - "No layout set for the appender named [{}].", name); - errors++; - } - - if(this.qw == null) { - getLogger().error("No writer set for the appender named [{}].", name); - errors++; - } - - // only error free appenders should be activated - if(errors == 0) { - super.activateOptions(); - } + public + void activateOptions() { } + /** This method is called by the {@link AppenderSkeleton#doAppend} method. @@ -159,7 +144,9 @@ public void activateOptions() { layout. */ - public void append(LoggingEvent event) { + public + void append(LoggingEvent event) { + // Reminder: the nesting of calls is: // // doAppend() @@ -168,12 +155,12 @@ public void append(LoggingEvent event) { // - append(); // - checkEntryConditions(); // - subAppend(); - if (!checkEntryConditions()) { + + if(!checkEntryConditions()) { return; } - subAppend(event); - } + } /** This method determines if there is a sense in attempting to append. @@ -181,23 +168,27 @@ public void append(LoggingEvent event) {

    It checks whether there is a set output target and also if there is a set layout. If these checks fail, then the boolean value false is returned. */ - protected boolean checkEntryConditions() { - if (this.closed) { - getNonFloodingLogger().warn("Not allowed to write to a closed appender."); - + protected + boolean checkEntryConditions() { + if(this.closed) { + LogLog.warn("Not allowed to write to a closed appender."); return false; } - if (this.qw == null) { - getNonFloodingLogger().error( - "No output stream or file set for the appender named [{}].", name); + if(this.qw == null) { + errorHandler.error("No output stream or file set for the appender named ["+ + name+"]."); + return false; + } + if(this.layout == null) { + errorHandler.error("No layout set for the appender named ["+ name+"]."); return false; } - return true; } + /** Close this appender instance. The underlying stream or writer is also closed. @@ -206,30 +197,33 @@ protected boolean checkEntryConditions() { @see #setWriter @since 0.8.4 */ - public synchronized void close() { - if (this.closed) { - return; + public + synchronized + void close() { + if(this.closed) { + return; } - this.closed = true; - closeWriter(); + writeFooter(); + reset(); } /** * Close the underlying {@link java.io.Writer}. * */ protected void closeWriter() { - if (this.qw != null) { + if(qw != null) { try { - // before closing we have to output out layout's footer - writeFooter(); - this.qw.close(); - this.qw = null; - } catch (IOException e) { - getLogger().error("Could not close writer for WriterAppener named "+name, e); + qw.close(); + } catch(IOException e) { + if (e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + // There is do need to invoke an error handler at this late + // stage. + LogLog.error("Could not close " + qw, e); } } - } /** @@ -238,24 +232,25 @@ protected void closeWriter() { encoding property. If the encoding value is specified incorrectly the writer will be opened using the default system encoding (an error message will be printed to the loglog. */ - protected OutputStreamWriter createWriter(OutputStream os) { + protected + OutputStreamWriter createWriter(OutputStream os) { OutputStreamWriter retval = null; String enc = getEncoding(); - - if (enc != null) { + if(enc != null) { try { - retval = new OutputStreamWriter(os, enc); - } catch (IOException e) { - getLogger().warn("Error initializing output writer."); - getLogger().warn("Unsupported encoding?"); + retval = new OutputStreamWriter(os, enc); + } catch(IOException e) { + if (e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.warn("Error initializing output writer."); + LogLog.warn("Unsupported encoding?"); } } - - if (retval == null) { + if(retval == null) { retval = new OutputStreamWriter(os); } - return retval; } @@ -267,63 +262,22 @@ public void setEncoding(String value) { encoding = value; } - /** - * Set the {@link org.apache.log4j.spi.ErrorHandler} for this WriterAppender and also the - * underlying {@link QuietWriter} if any. - * @deprecated - */ - public synchronized void setErrorHandler(org.apache.log4j.spi.ErrorHandler eh) { - if(eh == null) { - getLogger().warn("You have tried to set a null error-handler."); - } else { - this.errorHandler = eh; - if(this.qw != null) { - this.qw.setErrorHandler(eh); - } - } - } - - private static final class DefaultErrorHandler implements ErrorHandler { - private final WriterAppender appender; - public DefaultErrorHandler(final WriterAppender appender) { - this.appender = appender; - } - /**@since 1.2*/ - public void setLogger(Logger logger) { - } - public void error(String message, Exception ioe, int errorCode) { - appender.active = false; - appender.getNonFloodingLogger().error("IO failure for appender named "+ appender.getName(), ioe); - } - public void error(String message) { - } - /**@since 1.2*/ - public void error(String message, Exception e, int errorCode, LoggingEvent event) { - } - /**@since 1.2*/ - public void setAppender(Appender appender) { - - } - /**@since 1.2*/ - public void setBackupAppender(Appender appender) { - - } - - public void activateOptions() { - } - - } - - protected QuietWriter createQuietWriter(final Writer writer) { - ErrorHandler handler = errorHandler; - if (handler == null) { - handler = new DefaultErrorHandler(this); - } - return new QuietWriter(writer, handler); + /** + Set the {@link ErrorHandler} for this WriterAppender and also the + underlying {@link QuietWriter} if any. */ + public synchronized void setErrorHandler(ErrorHandler eh) { + if(eh == null) { + LogLog.warn("You have tried to set a null error-handler."); + } else { + this.errorHandler = eh; + if(this.qw != null) { + this.qw.setErrorHandler(eh); + } } + } /**

    Sets the Writer where the log output will go. The @@ -338,94 +292,98 @@ protected QuietWriter createQuietWriter(final Writer writer) {

    @param writer An already opened Writer. */ public synchronized void setWriter(Writer writer) { - // close any previously opened writer - closeWriter(); - - this.qw = createQuietWriter(writer); + reset(); + this.qw = new QuietWriter(writer, errorHandler); + //this.tp = new TracerPrintWriter(qw); writeHeader(); } + /** - * Actual writing occurs here. - *

    Most subclasses of WriterAppender will need to override - * this method. - * - * @since 0.9.0 - * */ - protected void subAppend(LoggingEvent event) { - if(!isActive()) { - return; + Actual writing occurs here. + +

    Most subclasses of WriterAppender will need to + override this method. + + @since 0.9.0 */ + protected + void subAppend(LoggingEvent event) { + this.qw.write(this.layout.format(event)); + + if(layout.ignoresThrowable()) { + String[] s = event.getThrowableStrRep(); + if (s != null) { + int len = s.length; + for(int i = 0; i < len; i++) { + this.qw.write(s[i]); + this.qw.write(Layout.LINE_SEP); + } + } } - - this.qw.write(this.layout.format(event)); - - if (layout.ignoresThrowable()) { - String[] s = event.getThrowableStrRep(); - if (s != null) { - int len = s.length; + if(shouldFlush(event)) { + this.qw.flush(); + } + } - for (int i = 0; i < len; i++) { - this.qw.write(s[i]); - this.qw.write(Layout.LINE_SEP); - } - } - } - if (this.immediateFlush) { - this.qw.flush(); - } - } - /** - * Gets whether appender requires a layout. - * @return false - */ - public boolean requiresLayout() { - return true; + /** + The WriterAppender requires a layout. Hence, this method returns + true. + */ + public + boolean requiresLayout() { + return true; } /** - * Clear internal references to the writer and other variables. - * - * Subclasses can override this method for an alternate closing - * behavior. - * - * @deprecated Use {@link #closeWriter} method instead. - * */ - protected void reset() { + Clear internal references to the writer and other variables. + + Subclasses can override this method for an alternate closing + behavior. */ + protected + void reset() { closeWriter(); this.qw = null; + //this.tp = null; } + /** - * Write a footer as produced by the embedded layout's {@link - * Layout#getFooter} method. - * */ - protected void writeFooter() { - if (layout != null) { + Write a footer as produced by the embedded layout's {@link + Layout#getFooter} method. */ + protected + void writeFooter() { + if(layout != null) { String f = layout.getFooter(); - - if ((f != null) && (this.qw != null)) { - this.qw.write(f); - this.qw.flush(); + if(f != null && this.qw != null) { + this.qw.write(f); + this.qw.flush(); } } } /** - * Write a header as produced by the embedded layout's {@link - * Layout#getHeader} method. - * */ - protected void writeHeader() { - if (layout != null) { + Write a header as produced by the embedded layout's {@link + Layout#getHeader} method. */ + protected + void writeHeader() { + if(layout != null) { String h = layout.getHeader(); - - if ((h != null) && (this.qw != null)) { - this.qw.write(h); - } + if(h != null && this.qw != null) { + this.qw.write(h); + } } } - - + + /** + * Determines whether the writer should be flushed after + * this event is written. + * + * @since 1.2.16 + */ + protected boolean shouldFlush(final LoggingEvent event) { + return immediateFlush; + } } diff --git a/src/main/java/org/apache/log4j/concurrency.txt b/src/main/java/org/apache/log4j/concurrency.txt deleted file mode 100644 index 8b895a7faa..0000000000 --- a/src/main/java/org/apache/log4j/concurrency.txt +++ /dev/null @@ -1,30 +0,0 @@ - -This document describes the concurrency model used in some of the -log4j core classes such as Logger (i.e. Category) and Hierarchy. - -Concurrency primitives in these classes must be studied carefully -because concurrency problems are usually hard to reproduce. Moreover, -since log4j is a tool to diagnose problems, the correctness of the -diagnosis tool (i.e log4j) must be guaranteed. - -We must also recognize that the data in Logger and Hierarchy are read -frequently and written to rarely. Up to and including log4j 1.2, we -did not differentiate between read and write operations. Instead, a -coarse object-wide locks were used which treated reads the same as -writes. This serializes some logging operations. A better approach -would be to allow simultaneous reads but exclusive writes. - -For this purpose log4j 1.3 includes a ReaderWriterLock that allow -simultaneous reads but exclusive writes. When readers and writers -compete for the lock, preference is given to writers. See -o.a.l.helpers.ReaderWriterLock.java for source code which is -remarkably simple. - -The ReaderWriterLock is not reentrant. Thus, we must make sure that a -writer owning the lock does try to reacquire the lock because any such -attempt would result in a deadlock. Similarly, it is not safe for a -reader owning the lock to try to reacquire it. This condition can be -verified only if few simple instructions are allowed between the line -acquiring the lock and the line releasing it. If the code inside a -protected block is complex, then either it is wrong or our model needs -to be changed. diff --git a/src/main/java/org/apache/log4j/concurrent/ConcurrentAppender.java b/src/main/java/org/apache/log4j/concurrent/ConcurrentAppender.java deleted file mode 100644 index fcf99dc224..0000000000 --- a/src/main/java/org/apache/log4j/concurrent/ConcurrentAppender.java +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.concurrent; - -import org.apache.log4j.Layout; -import org.apache.log4j.Appender; -import org.apache.log4j.Priority; -import org.apache.log4j.spi.ComponentBase; -import org.apache.log4j.spi.Filter; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.OptionHandler; - -/** - * Base class for appenders that can benefit from a concurrency strategy. - * Classes derived from this appender may have the {@link #append} method - * called by multiple threads. Derived classes must also override {@link - * #internalClose}. - *

    - * Locking strategy: Internally, there is a read-write lock to handle - * concurrent modification. A write lock is obtained to change states - * (including before {@link #close}.) A read lock is obtained to read - * options. Subclasses interested in state may check state using a public - * method or within their own {@link #append} method. - *

    - *

    - * If Thread.interrupt() is called during append of the logger thread, - * the customary behavior in this package is to stop appending. - *

    - *

    - * This class is heavily based on the {@link - * #org.apache.log4j.AppenderSkeleton} class. It may be a useful base class - * for creating appenders that can benefit from concurrent I/O access. - *

    - * - * @author Elias Ross - */ -public abstract class ConcurrentAppender - extends ComponentBase implements Appender, OptionHandler -{ - - /** - * The layout variable does not need to be set if the appender - * implementation has its own layout. - */ - private Layout layout; - - /** - * The name of this appender. - */ - protected String name; - - /** - * There is no level threshold filtering by default. - */ - private volatile Priority threshold; - - /** - * Internal class, internally locked. - */ - private FilterChain filters = new FilterChain(); - - /** - * Is this appender closed? - */ - private SynchronizedBoolean closed = new SynchronizedBoolean(false); - - /** - * Set to true when the appender is activated. - * Subclasses can set this to false to indicate things are not in order. - */ - protected SynchronizedBoolean active = new SynchronizedBoolean(false); - - /** - * The guard prevents an appender from repeatedly calling its own doAppend - * method. This prevents same-thread re-entry looping. - */ - private ThreadLocal guard = new ThreadLocal(); - - /** - * A write lock is obtained to change options, a read lock is obtained to - * append events. - * This is a re-entrant writer-preference read-write lock. - */ - protected ReadWriteLock lock = new ReentrantWriterPreferenceReadWriteLock(); - - /** - * Constructs a ConcurrentAppender. - * - * @param isActive true if appender is ready for use upon construction. - */ - protected ConcurrentAppender(final boolean isActive) { - active.set(isActive); - } - - /** - * Derived appenders should override this method if option structure - * requires it. - * By default, sets {@link #active} to true. - */ - public void activateOptions() { - active.set(true); - } - - /** - * Indicates if the appender is active and not closed. - */ - public boolean isActive() { - return active.get() && !closed.get(); - } - - /** - * Adds a filter to end of the filter list. - * @param filter filter to use; cannot be null - */ - public void addFilter(Filter filter) { - filters.addFilter(filter); - } - - /** - * Clears the filters chain. - */ - public void clearFilters() { - filters.clear(); - } - - /** - * Returns the first {@link Filter}. - */ - public Filter getFilter() { - return filters.getHead(); - } - - /** - * Returns the layout of this appender. May return null if not set. - */ - public Layout getLayout() { - return this.layout; - } - - /** - * Returns the name of this appender. - */ - public final String getName() { - return this.name; - } - - /** - * Returns this appender's threshold level. See the {@link #setThreshold} - * method for the meaning of this option. - */ - public Priority getThreshold() { - return threshold; - } - - /** - * Returns true if the message level is below the appender's threshold. If - * there is no threshold set, returns true. - */ - public boolean isAsSevereAsThreshold(final Priority level) { - Priority copy = threshold; - return ((copy == null) || level.isGreaterOrEqual(copy)); - } - - /** - * Performs threshold checks and checks filters before delegating actual - * logging to the subclasses specific {@link #append} method. - * This implementation also checks if this thread already is logging using - * this appender, preventing possible stack overflow. - */ - public final void doAppend(LoggingEvent event) { - - if (!isAsSevereAsThreshold(event.getLevel())) - return; - - if (!filters.accept(event)) - return; - - // Prevent concurrent re-entry by this thread - // (There might be a cheaper way to do this) - // (Or maybe this lock is not necessary) - if (guard.get() != null) - return; - - guard.set(this); // arbitrary thread lock object - try { - - lock.readLock().acquire(); - try { - - - if (closed.get()) { - getNonFloodingLogger().error( - "Attempted to use closed appender named [" + name + "]."); - return; - } - - if (!active.get()) { - getNonFloodingLogger().error( - "Attempted to log with inactive named [" + name + "]."); - return; - } - - append(event); - - } finally { - lock.readLock().release(); - } - - } catch (InterruptedException e) { - getLogger().info("interrupted", e); - } finally { - guard.set(null); - } - } - - /** - * Sets the layout for this appender. Note that some appenders have their own - * (fixed) layouts or do not use one. For example, the {@link - * org.apache.log4j.net.SocketAppender} ignores the layout set here. - *

    - * Note that the implementation of {@link Layout} must be thread-safe. - * Common layouts such as {@link org.apache.log4j.PatternLayout} are - * thread-safe. - *

    - * - * @param layout new layout to use; may be null - */ - public void setLayout(Layout layout) { - this.layout = layout; - } - - /** - * Sets the name of this Appender. - */ - public void setName(String name) { - this.name = name; - } - - /** - * Sets the threshold level. - * All log events with lower level than the threshold level are ignored by - * the appender. - * - * @param threshold new threshold; may be null - */ - public void setThreshold(final Priority threshold) { - this.threshold = threshold; - } - - /** - * Returns true if this appender is closed. - * An appender, once closed, is closed forever. - */ - public boolean getClosed() { - return closed.get(); - } - - /** - * Cleans up this appender. - * Marked as final to prevent subclasses from accidentally - * overriding and forgetting to call super.close() or obtain a - * write lock. - * Calls {@link #internalClose} when completed. - * Implementation note: Obtains a write lock before starting close. - * Calling this method more than once does nothing. - * @throws RuntimeException if the thread is interrupted - */ - public final void close() { - boolean wasClosed; - try { - lock.writeLock().acquire(); - } catch (InterruptedException e) { - getLogger().warn("interrupted", e); - return; - } - try { - wasClosed = closed.set(true); - } finally { - lock.writeLock().release(); - } - - if (!wasClosed) - internalClose(); - } - - /** - * Called to check if the appender is closed. - */ - public boolean isClosed() { - return closed.get(); - } - - private static final org.apache.log4j.spi.ErrorHandler ERROR_HANDLER = - new org.apache.log4j.helpers.OnlyOnceErrorHandler(); - - public final org.apache.log4j.spi.ErrorHandler getErrorHandler() { - return ERROR_HANDLER; - } - - public final void setErrorHandler(org.apache.log4j.spi.ErrorHandler eh) { - } - - /** - * Returns a string representation of this object. - */ - public String toString() { - return super.toString() + " name=" + name + - " threshold=" + threshold + - " layout=" + layout + - " filters=" + filters; - } - - // PROTECTED METHODS - - /** - * Subclasses of ConcurrentAppender should implement this method - * to perform actual logging. - * This object holds a read lock during this method. This method may be - * called simultaneously by multiple threads. - */ - protected abstract void append(LoggingEvent event); - - /** - * Subclasses must implement their own close routines. - * This method is called by the {@link #close} method. - * This is guaranteed to be called only once, even if {@link #close} is - * invoked more than once. - * Note that further locking is not required, as {@link #append} can no - * longer be called. - */ - protected abstract void internalClose(); - - /** - * Finalizes this appender by calling this {@link #close} method. - */ - protected void finalize() { - if (!getClosed()) - getLogger().debug("Finalizing appender named [{}].", name); - close(); - } - - /** - * A simple linked-list data structure containing filters. - */ - private static class FilterChain { - - private Filter headFilter = null; - private Filter tailFilter = null; - - public synchronized boolean accept(LoggingEvent event) { - Filter f = headFilter; - while (f != null) { - switch (f.decide(event)) { - case Filter.DENY: - return false; - case Filter.ACCEPT: - return true; - case Filter.NEUTRAL: - f = f.getNext(); - } - } - return true; - } - - public synchronized void addFilter(Filter newFilter) { - if (newFilter == null) - throw new NullPointerException(); - if (headFilter == null) { - headFilter = newFilter; - tailFilter = newFilter; - } else { - tailFilter.setNext(newFilter); - tailFilter = newFilter; - } - } - - public synchronized Filter getHead() { - return headFilter; - } - - public synchronized void clear() { - headFilter = null; - tailFilter = null; - } - - public synchronized String toString() { - StringBuffer sb = new StringBuffer(); - Filter f = headFilter; - while (f != null) { - sb.append(f); - f = f.getNext(); - if (f != null) - sb.append(','); - } - return sb.toString(); - } - - } - -} - diff --git a/src/main/java/org/apache/log4j/concurrent/ConsoleAppender.java b/src/main/java/org/apache/log4j/concurrent/ConsoleAppender.java deleted file mode 100644 index 2d7e8b90f9..0000000000 --- a/src/main/java/org/apache/log4j/concurrent/ConsoleAppender.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.concurrent; - -import java.io.IOException; -import java.io.OutputStream; -import org.apache.log4j.Layout; - - -/** - * ConsoleAppender appends log events to System.out or - * System.err using a layout specified by the user. The - * default target is System.out. - * - * @author Ceki Gülcü - * @author Curt Arnold - * @since 1.1 */ -public class ConsoleAppender extends WriterAppender { - public static final String SYSTEM_OUT = "System.out"; - public static final String SYSTEM_ERR = "System.err"; - protected String target = SYSTEM_OUT; - - /** - * Determines if the appender honors reassignments of System.out - * or System.err made after configuration. - */ - private boolean follow = false; - - - /** - * Constructs an unconfigured appender. - */ - public ConsoleAppender() { - } - - /** - * Creates a configured appender. - * - * @param layout layout, may not be null. - */ - public ConsoleAppender(final Layout layout) { - setLayout(layout); - activateOptions(); - } - - /** - * Creates a configured appender. - * @param layout layout, may not be null. - * @param targetStr target, either "System.err" or "System.out". - */ - public ConsoleAppender(final Layout layout, final String targetStr) { - setLayout(layout); - setTarget(targetStr); - activateOptions(); - } - - /** - * Sets the value of the Target option. Recognized values - * are "System.out" and "System.err". Any other value will be - * ignored. - * */ - public void setTarget(final String value) { - String v = value.trim(); - - if (SYSTEM_OUT.equalsIgnoreCase(v)) { - target = SYSTEM_OUT; - } else if (SYSTEM_ERR.equalsIgnoreCase(v)) { - target = SYSTEM_ERR; - } else { - getLogger().warn("[{}] should be System.out or System.err.", value); - getLogger().warn("Using previously set target, System.out by default."); - } - } - - /** - * Returns the current value of the Target property. The - * default value of the option is "System.out". - * - * See also {@link #setTarget}. - * */ - public String getTarget() { - return target; - } - - /** - * Sets whether the appender honors reassignments of System.out - * or System.err made after configuration. - * @param newValue if true, appender will use value of System.out or - * System.err in force at the time when logging events are appended. - * @since 1.2.13 - */ - public final void setFollow(final boolean newValue) { - follow = newValue; - } - - /** - * Gets whether the appender honors reassignments of System.out - * or System.err made after configuration. - * @return true if appender will use value of System.out or - * System.err in force at the time when logging events are appended. - * @since 1.2.13 - */ - public final boolean getFollow() { - return follow; - } - - - /** - * Prepares the appender for use. - */ - public void activateOptions() { - if (follow) { - if (target.equals(SYSTEM_ERR)) { - setWriter(createWriter(new SystemErrStream())); - } else { - setWriter(createWriter(new SystemOutStream())); - } - } else { - if (target.equals(SYSTEM_ERR)) { - setWriter(createWriter(System.err)); - } else { - setWriter(createWriter(System.out)); - } - } - - super.activateOptions(); - } - - /** - * {@inheritDoc} - */ - protected - final - void closeWriter() { - if (follow) { - super.closeWriter(); - } - } - - - /** - * An implementation of OutputStream that redirects to the - * current System.err. - * - */ - private static class SystemErrStream extends OutputStream { - public SystemErrStream() { - } - - public void close() { - } - - public void flush() { - System.err.flush(); - } - - public void write(final byte[] b) throws IOException { - System.err.write(b); - } - - public void write(final byte[] b, final int off, final int len) - throws IOException { - System.err.write(b, off, len); - } - - public void write(final int b) throws IOException { - System.err.write(b); - } - } - - /** - * An implementation of OutputStream that redirects to the - * current System.out. - * - */ - private static class SystemOutStream extends OutputStream { - public SystemOutStream() { - } - - public void close() { - } - - public void flush() { - System.out.flush(); - } - - public void write(final byte[] b) throws IOException { - System.out.write(b); - } - - public void write(final byte[] b, final int off, final int len) - throws IOException { - System.out.write(b, off, len); - } - - public void write(final int b) throws IOException { - System.out.write(b); - } - } -} - - diff --git a/src/main/java/org/apache/log4j/concurrent/FileAppender.java b/src/main/java/org/apache/log4j/concurrent/FileAppender.java deleted file mode 100644 index 7472eff572..0000000000 --- a/src/main/java/org/apache/log4j/concurrent/FileAppender.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.concurrent; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.Writer; - -import org.apache.log4j.Layout; -import org.apache.log4j.helpers.OptionConverter; - - -// Contibutors: Jens Uwe Pipka -// Ben Sandee - -/** - * FileAppender appends log events to a file. - * - *

    Support for java.io.Writer 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 { - - public static final int DEFAULT_BUFFER_SIZE = 8 * 1024; - - /** - * Controls whether to append to or truncate an existing file. - * The default value for this variable is - * true, meaning that by default a FileAppender will - * append to an existing file and not truncate it. - * - *

    This option is meaningful only if the FileAppender opens the file. - */ - protected boolean fileAppend = true; - - /** - The name of the log file. */ - protected String fileName = null; - - /** - Do we do bufferedIO? */ - protected boolean bufferedIO = true; - - /** - The size of the IO buffer. Default is 8K. */ - protected int bufferSize = DEFAULT_BUFFER_SIZE; - - /** - The default constructor does not do anything. - */ - public FileAppender() { - } - - /** - Instantiate a FileAppender and open the file - designated by filename. The opened filename will - become the output destination for this appender. - -

    If the append parameter is true, the file will be - appended to. Otherwise, the file designated by - filename will be truncated before being opened. - -

    If the bufferedIO parameter is true, - then buffered IO will be used to write to the output file. - - */ - public FileAppender( - Layout layout, String filename, boolean append, boolean bufferedIO, - int bufferSize) throws IOException { - setLayout(layout); - this.setFile(filename, append, bufferedIO, bufferSize); - activateOptions(); - } - - /** - Instantiate a FileAppender and open the file designated by - filename. The opened filename will become the output - destination for this appender. - -

    If the append parameter is true, the file will be - appended to. Otherwise, the file designated by - filename will be truncated before being opened. - */ - public FileAppender(Layout layout, String filename, boolean append) - throws IOException { - this(layout, filename, append, false, DEFAULT_BUFFER_SIZE); - } - - /** - Instantiate a FileAppender and open the file designated by - filename. The opened filename will become the output - destination for this appender. - -

    The file will be appended to. */ - public FileAppender(Layout layout, String filename) throws IOException { - this(layout, filename, true); - activateOptions(); - } - - /** - The File property takes a string value which should be the - name of the file to append to. - -

    Note that the special values - "System.out" or "System.err" are no longer honored. - -

    Note: Actual opening of the file is made when {@link - #activateOptions} is called, not when the options are set. */ - public void setFile(String file) { - // Trim spaces from both ends. The users probably does not want - // trailing spaces in file names. - String val = file.trim(); - fileName = OptionConverter.stripDuplicateBackslashes(val); - } - - /** - Returns the value of the Append option. - */ - public boolean getAppend() { - return fileAppend; - } - - /** Returns the value of the File option. */ - public String getFile() { - return fileName; - } - - /** - If the value of File is not null, then {@link - #setFile} is called with the values of File and - Append properties. - - @since 0.8.1 */ - public void activateOptions() { - if (fileName != null) { - try { - setFile(fileName, fileAppend, bufferedIO, bufferSize); - super.activateOptions(); - } catch (java.io.IOException e) { - getLogger().error( - "setFile(" + fileName + "," + fileAppend + ") call failed.", e); - } - } else { - getLogger().error("File option not set for appender [{}].", name); - getLogger().warn("Are you using FileAppender instead of ConsoleAppender?"); - } - } - - /** - * Closes the previously opened file. - * - * @deprecated Use the super class' {@link #closeWriter} method instead. - */ - protected void closeFile() { - closeWriter(); - } - - /** - Get the value of the BufferedIO option. - -

    BufferedIO will significantly increase performance on heavily - loaded systems. - - */ - public boolean getBufferedIO() { - return this.bufferedIO; - } - - /** - Get the size of the IO buffer. - */ - public int getBufferSize() { - return this.bufferSize; - } - - /** - The Append option takes a boolean value. It is set to - true by default. If true, then File - will be opened in append mode by {@link #setFile setFile} (see - above). Otherwise, {@link #setFile setFile} will open - File in truncate mode. - -

    Note: Actual opening of the file is made when {@link - #activateOptions} is called, not when the options are set. - */ - public void setAppend(boolean flag) { - fileAppend = flag; - } - - /** - The BufferedIO option takes a boolean value. It is set to - false by default. If true, then File - will be opened and the resulting {@link java.io.Writer} wrapped - around a {@link BufferedWriter}. - - BufferedIO will significantly increase performance on heavily - loaded systems. - - */ - public void setBufferedIO(boolean bufferedIO) { - this.bufferedIO = bufferedIO; - } - - /** - Set the size of the IO buffer. - */ - public void setBufferSize(int bufferSize) { - this.bufferSize = bufferSize; - } - - /** -

    Sets and opens the file where the log output will - go. The specified file must be writable. - -

    If there was already an opened file, then the previous file - is closed first. - -

    Do not use this method directly. To configure a FileAppender - or one of its subclasses, set its properties one by one and then - call activateOptions. - - @param filename The path to the log file. - @param append If true will append to fileName. Otherwise will - truncate fileName. - @param bufferedIO - @param bufferSize - - @throws IOException - - */ - public void setFile( - String filename, boolean append, boolean bufferedIO, int bufferSize) - throws IOException { - getLogger().debug("setFile called: {}, {}", filename, append ? Boolean.TRUE : Boolean.FALSE); - - this.fileAppend = append; - this.bufferedIO = bufferedIO; - this.fileName = filename; - this.bufferSize = bufferSize; - - FileOutputStream ostream = createOutputStream(); - Writer writer = createWriter(ostream); - if (bufferedIO) { - writer = new BufferedWriter(writer, bufferSize); - } - - setWriter(writer); - getLogger().debug("setFile ended"); - } - - protected FileOutputStream createOutputStream() - throws IOException - { - try { - // - // attempt to create file - // - return new FileOutputStream(fileName, fileAppend); - } catch(FileNotFoundException ex) { - // - // if parent directory does not exist then - // attempt to create it and try to create file - // see bug 9150 - // - File parentDir = new File(new File(fileName).getParent()); - if (!parentDir.exists() && parentDir.mkdirs()) { - return new FileOutputStream(fileName, fileAppend); - } else { - throw ex; - } - } - } - -} - diff --git a/src/main/java/org/apache/log4j/concurrent/ReadWriteLock.java b/src/main/java/org/apache/log4j/concurrent/ReadWriteLock.java deleted file mode 100644 index cb05c3d9e0..0000000000 --- a/src/main/java/org/apache/log4j/concurrent/ReadWriteLock.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - File: ReadWriteLock.java - - Originally written by Doug Lea and released into the public domain. - This may be used for any purposes whatsoever without acknowledgment. - Thanks for the assistance and support of Sun Microsystems Labs, - and everyone contributing, testing, and using this code. - - History: - Date Who What - 11Jun1998 dl Create public version -*/ - - -package org.apache.log4j.concurrent; - - -/** - * ReadWriteLocks maintain a pair of associated locks. - * The readLock may be held simultanously by multiple - * reader threads, so long as there are no writers. The writeLock - * is exclusive. ReadWrite locks are generally preferable to - * plain Sync locks or synchronized methods in cases where: - *

      - *
    • The methods in a class can be cleanly separated into - * those that only access (read) data vs those that - * modify (write). - *
    • Target applications generally have more readers than writers. - *
    • The methods are relatively time-consuming (as a rough - * rule of thumb, exceed more than a hundred instructions), so it - * pays to introduce a bit more overhead associated with - * ReadWrite locks compared to simple synchronized methods etc - * in order to allow concurrency among reader threads. - * - *
    - * Different implementation classes differ in policies surrounding - * which threads to prefer when there is - * contention. By far, the most commonly useful policy is - * WriterPreferenceReadWriteLock. The other implementations - * are targeted for less common, niche applications. - *

    - * Standard usage: - *

    - * class X {
    - *   ReadWriteLock rw;
    - *   // ...
    - *
    - *   public void read() throws InterruptedException { 
    - *     rw.readLock().acquire();
    - *     try {
    - *       // ... do the read
    - *     }
    - *     finally {
    - *       rw.readlock().release()
    - *     }
    - *   }
    - *
    - *
    - *   public void write() throws InterruptedException { 
    - *     rw.writeLock().acquire();
    - *     try {
    - *       // ... do the write
    - *     }
    - *     finally {
    - *       rw.writelock().release()
    - *     }
    - *   }
    - * }
    - * 
    - * @see Sync - *

    [ Introduction to this package. ] - -**/ - -public interface ReadWriteLock { - /** get the readLock **/ - Sync readLock(); - - /** get the writeLock **/ - Sync writeLock(); -} - diff --git a/src/main/java/org/apache/log4j/concurrent/ReentrantWriterPreferenceReadWriteLock.java b/src/main/java/org/apache/log4j/concurrent/ReentrantWriterPreferenceReadWriteLock.java deleted file mode 100644 index 083c5fd693..0000000000 --- a/src/main/java/org/apache/log4j/concurrent/ReentrantWriterPreferenceReadWriteLock.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - File: ReentrantWriterPreferenceReadWriteLock.java - - Originally written by Doug Lea and released into the public domain. - This may be used for any purposes whatsoever without acknowledgment. - Thanks for the assistance and support of Sun Microsystems Labs, - and everyone contributing, testing, and using this code. - - History: - Date Who What - 26aug1998 dl Create public version - 7sep2000 dl Readers are now also reentrant - 19jan2001 dl Allow read->write upgrades if the only reader - 10dec2002 dl Throw IllegalStateException on extra release -*/ - -package org.apache.log4j.concurrent; -import java.util.*; - -/** - * A writer-preference ReadWriteLock that allows both readers and - * writers to reacquire - * read or write locks in the style of a ReentrantLock. - * Readers are not allowed until all write locks held by - * the writing thread have been released. - * Among other applications, reentrancy can be useful when - * write locks are held during calls or callbacks to methods that perform - * reads under read locks. - *

    - * Sample usage. Here is a code sketch showing how to exploit - * reentrancy to perform lock downgrading after updating a cache: - *

    - * class CachedData {
    - *   Object data;
    - *   volatile boolean cacheValid;
    - *   ReentrantWriterPreferenceReadWriteLock rwl = ...
    - *
    - *   void processCachedData() {
    - *     rwl.readLock().acquire();
    - *     if (!cacheValid) {
    - *
    - *        // upgrade lock:
    - *        rwl.readLock().release();   // must release first to obtain writelock
    - *        rwl.writeLock().acquire();
    - *        if (!cacheValid) { // recheck
    - *          data = ...
    - *          cacheValid = true;
    - *        }
    - *        // downgrade lock
    - *        rwl.readLock().acquire();  // reacquire read without giving up lock
    - *        rwl.writeLock().release(); // release write, still hold read
    - *     }
    - *
    - *     use(data);
    - *     rwl.readLock().release();
    - *   }
    - * }
    - * 
    - * - * - *

    [ Introduction to this package. ] - * @see ReentrantLock - **/ - -class ReentrantWriterPreferenceReadWriteLock extends WriterPreferenceReadWriteLock { - - /** Number of acquires on write lock by activeWriter_ thread **/ - protected long writeHolds_ = 0; - - /** Number of acquires on read lock by any reader thread **/ - protected HashMap readers_ = new HashMap(); - - /** cache/reuse the special Integer value one to speed up readlocks **/ - protected static final Integer IONE = new Integer(1); - - - protected boolean allowReader() { - return (activeWriter_ == null && waitingWriters_ == 0) || - activeWriter_ == Thread.currentThread(); - } - - protected synchronized boolean startRead() { - Thread t = Thread.currentThread(); - Object c = readers_.get(t); - if (c != null) { // already held -- just increment hold count - readers_.put(t, new Integer(((Integer)(c)).intValue()+1)); - ++activeReaders_; - return true; - } - else if (allowReader()) { - readers_.put(t, IONE); - ++activeReaders_; - return true; - } - else - return false; - } - - protected synchronized boolean startWrite() { - if (activeWriter_ == Thread.currentThread()) { // already held; re-acquire - ++writeHolds_; - return true; - } - else if (writeHolds_ == 0) { - if (activeReaders_ == 0 || - (readers_.size() == 1 && - readers_.get(Thread.currentThread()) != null)) { - activeWriter_ = Thread.currentThread(); - writeHolds_ = 1; - return true; - } - else - return false; - } - else - return false; - } - - - protected synchronized Signaller endRead() { - Thread t = Thread.currentThread(); - Object c = readers_.get(t); - if (c == null) - throw new IllegalStateException(); - --activeReaders_; - if (c != IONE) { // more than one hold; decrement count - int h = ((Integer)(c)).intValue()-1; - Integer ih = (h == 1)? IONE : new Integer(h); - readers_.put(t, ih); - return null; - } - else { - readers_.remove(t); - - if (writeHolds_ > 0) // a write lock is still held by current thread - return null; - else if (activeReaders_ == 0 && waitingWriters_ > 0) - return writerLock_; - else - return null; - } - } - - protected synchronized Signaller endWrite() { - --writeHolds_; - if (writeHolds_ > 0) // still being held - return null; - else { - activeWriter_ = null; - if (waitingReaders_ > 0 && allowReader()) - return readerLock_; - else if (waitingWriters_ > 0) - return writerLock_; - else - return null; - } - } - -} - diff --git a/src/main/java/org/apache/log4j/concurrent/RollingFileAppender.java b/src/main/java/org/apache/log4j/concurrent/RollingFileAppender.java deleted file mode 100644 index d35fe2d97c..0000000000 --- a/src/main/java/org/apache/log4j/concurrent/RollingFileAppender.java +++ /dev/null @@ -1,531 +0,0 @@ -/* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.concurrent; - -import org.apache.log4j.rolling.RollingPolicy; -import org.apache.log4j.rolling.RolloverDescription; -import org.apache.log4j.rolling.TriggeringPolicy; -import org.apache.log4j.rolling.helper.Action; -import org.apache.log4j.spi.LoggingEvent; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; - - -/** - * RollingFileAppender extends {@link FileAppender} to backup the log files - * depending on {@link RollingPolicy} and {@link TriggeringPolicy}. - *

    - * To be of any use, a RollingFileAppender instance must have both - * a RollingPolicy and a TriggeringPolicy set up. - * However, if its RollingPolicy also implements the - * TriggeringPolicy interface, then only the former needs to be - * set up. For example, {@link TimeBasedRollingPolicy} acts both as a - * RollingPolicy and a TriggeringPolicy. - * - *

    RollingFileAppender can be configured programattically or - * using {@link org.apache.log4j.joran.JoranConfigurator}. Here is a sample - * configration file: - -

    <?xml version="1.0" encoding="UTF-8" ?>
    -<!DOCTYPE log4j:configuration>
    -
    -<log4j:configuration debug="true">
    -
    -  <appender name="ROLL" class="org.apache.log4j.rolling.RollingFileAppender">
    -    <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
    -      <param name="FileNamePattern" value="/wombat/foo.%d{yyyy-MM}.gz"/>
    -    </rollingPolicy>
    -
    -    <layout class="org.apache.log4j.PatternLayout">
    -      <param name="ConversionPattern" value="%c{1} - %m%n"/>
    -    </layout>
    -  </appender>
    -
    -  <root">
    -    <appender-ref ref="ROLL"/>
    -  </root>
    -
    -</log4j:configuration>
    -
    - - *

    This configuration file specifies a monthly rollover schedule including - * automatic compression of the archived files. See - * {@link TimeBasedRollingPolicy} for more details. - * - * @author Heinz Richter - * @author Ceki Gülcü - * @author Elias Ross - * @since 1.3 - * */ -public final class RollingFileAppender extends FileAppender { - /** - * Triggering policy. - */ - private TriggeringPolicy triggeringPolicy; - - /** - * Rolling policy. - */ - private RollingPolicy rollingPolicy; - - /** - * Length of current active log file. - */ - private long fileLength = 0; - - /** - * Lock to protect the length. - */ - private Object fileLengthLock = new Object(); - - /** - * Asynchronous action (like compression) from previous rollover. - */ - private Action lastRolloverAsyncAction = null; - - /** - * Construct a new instance. - */ - public RollingFileAppender() { - } - - /** - * Prepare instance of use. - */ - public void activateOptions() { - if (rollingPolicy == null) { - getLogger().warn( - "Please set a rolling policy for the RollingFileAppender named '{}'", - getName()); - - return; - } - - // - // if no explicit triggering policy and rolling policy is both. - // - if ( - (triggeringPolicy == null) && rollingPolicy instanceof TriggeringPolicy) { - triggeringPolicy = (TriggeringPolicy) rollingPolicy; - } - - if (triggeringPolicy == null) { - getLogger().warn( - "Please set a TriggeringPolicy for the RollingFileAppender named '{}'", - getName()); - - return; - } - - Exception exception = null; - - try { - lock.writeLock().acquire(); - } catch (InterruptedException e) { - getLogger().warn("interrupted", e); - return; - } - try { - triggeringPolicy.activateOptions(); - rollingPolicy.activateOptions(); - - try { - RolloverDescription rollover = - rollingPolicy.initialize(getFile(), getAppend()); - - if (rollover != null) { - Action syncAction = rollover.getSynchronous(); - - if (syncAction != null) { - syncAction.execute(); - } - - setFile(rollover.getActiveFileName()); - setAppend(rollover.getAppend()); - lastRolloverAsyncAction = rollover.getAsynchronous(); - - if (lastRolloverAsyncAction != null) { - Thread t = new Thread(lastRolloverAsyncAction); - t.setName("log4j-rollover-" + getName()); - t.start(); - } - } - - File activeFile = new File(getFile()); - - if (getAppend()) { - setFileLength(activeFile.length()); - } else { - setFileLength(0); - } - - super.activateOptions(); - } catch (Exception ex) { - exception = ex; - } - } finally { - lock.writeLock().release(); - } - - if (exception != null) { - getLogger().warn( - "Exception while initializing RollingFileAppender named '" + getName() - + "'", exception); - } - } - - /** - Implements the usual roll over behaviour. - -

    If MaxBackupIndex is positive, then files - {File.1, ..., File.MaxBackupIndex -1} - are renamed to {File.2, ..., - File.MaxBackupIndex}. Moreover, File is - renamed File.1 and closed. A new File is - created to receive further log output. - -

    If MaxBackupIndex is equal to zero, then the - File is truncated with no backup files created. - - * @return true if rollover performed. - */ - public boolean rollover() { - // - // can't roll without a policy - // - if (rollingPolicy != null) { - Exception exception = null; - - try { - lock.writeLock().acquire(); - } catch (InterruptedException e) { - getLogger().warn("interrupted", e); - return false; - } - try { - // - // if a previous async task is still running - // - if (lastRolloverAsyncAction != null) { - // - // block until complete - // - lastRolloverAsyncAction.close(); - - // - // or don't block and return to rollover later - // - //if (!lastRolloverAsyncAction.isComplete()) return false; - } - - try { - RolloverDescription rollover = rollingPolicy.rollover(getFile()); - - if (rollover != null) { - if (rollover.getActiveFileName().equals(getFile())) { - closeWriter(); - - boolean success = true; - - if (rollover.getSynchronous() != null) { - success = false; - - try { - success = rollover.getSynchronous().execute(); - } catch (Exception ex) { - exception = ex; - } - } - - if (success) { - if (rollover.getAppend()) { - setFileLength(new File(rollover.getActiveFileName()).length()); - } else { - setFileLength(0); - } - - if (rollover.getAsynchronous() != null) { - lastRolloverAsyncAction = rollover.getAsynchronous(); - Thread t = new Thread(lastRolloverAsyncAction); - t.setName("log4j-rollover-" + getName()); - t.start(); - } - - setFile( - rollover.getActiveFileName(), rollover.getAppend(), - bufferedIO, bufferSize); - } else { - setFile( - rollover.getActiveFileName(), true, bufferedIO, bufferSize); - - if (exception == null) { - getLogger().warn("Failure in post-close rollover action"); - } else { - getLogger().warn( - "Exception in post-close rollover action", exception); - } - } - } else { - Writer newWriter = - createWriter( - new FileOutputStream( - rollover.getActiveFileName(), rollover.getAppend())); - closeWriter(); - setFile(rollover.getActiveFileName()); - setWriter(newWriter); - - boolean success = true; - - if (rollover.getSynchronous() != null) { - success = false; - - try { - success = rollover.getSynchronous().execute(); - } catch (Exception ex) { - exception = ex; - } - } - - if (success) { - if (rollover.getAppend()) { - fileLength = new File(rollover.getActiveFileName()).length(); - } else { - fileLength = 0; - } - - if (rollover.getAsynchronous() != null) { - Thread t = new Thread(lastRolloverAsyncAction); - t.setName("log4j-rollover-" + getName()); - t.start(); - } - } - - writeHeader(); - } - - return true; - } - } catch (Exception ex) { - exception = ex; - } - } finally { - lock.writeLock().release(); - } - - if (exception != null) { - getLogger().warn( - "Exception during rollover, rollover deferred.", exception); - } - } - - return false; - } - - private boolean isTriggeringEvent(LoggingEvent event) { - return triggeringPolicy.isTriggeringEvent( - this, event, getFile(), getFileLength()); - } - - /** - * {@inheritDoc} - */ - protected void subAppend(final LoggingEvent event) { - // The rollover check must precede actual writing. This is the - // only correct behavior for time driven triggers. - if (isTriggeringEvent(event)) { - - // upgrade the lock - lock.readLock().release(); - try { - lock.writeLock().acquire(); - } catch (InterruptedException e) { - getLogger().warn("interrupted", e); - return; - } - try { - if (isTriggeringEvent(event)) { - rollover(); - } - } finally { - // downgrade the lock - try { - lock.readLock().acquire(); - } catch (InterruptedException e) { - getLogger().warn("interrupted", e); - return; - } - lock.writeLock().release(); - } - } - - super.subAppend(event); - } - - /** - * Get rolling policy. - * @return rolling policy. - */ - public RollingPolicy getRollingPolicy() { - return rollingPolicy; - } - - /** - * Get triggering policy. - * @return triggering policy. - */ - public TriggeringPolicy getTriggeringPolicy() { - return triggeringPolicy; - } - - /** - * Sets the rolling policy. - * @param policy rolling policy. - */ - public void setRollingPolicy(final RollingPolicy policy) { - rollingPolicy = policy; - } - - /** - * Set triggering policy. - * @param policy triggering policy. - */ - public void setTriggeringPolicy(final TriggeringPolicy policy) { - triggeringPolicy = policy; - } - - /** - * Close appender. Waits for any asynchronous file compression actions to be completed. - */ - public void internalClose() { - if (lastRolloverAsyncAction != null) { - lastRolloverAsyncAction.close(); - } - - super.internalClose(); - } - - /** - Returns an OutputStreamWriter when passed an OutputStream. The - encoding used will depend on the value of the - encoding property. If the encoding value is - specified incorrectly the writer will be opened using the default - system encoding (an error message will be printed to the loglog. - @param os output stream, may not be null. - @return new writer. - */ - protected OutputStreamWriter createWriter(final OutputStream os) { - return super.createWriter(new CountingOutputStream(os, this)); - } - - /** - * Get byte length of current active log file. - * @return byte length of current active log file. - */ - public long getFileLength() { - synchronized (fileLengthLock) { - return fileLength; - } - } - - private void setFileLength(long len) { - synchronized (fileLengthLock) { - fileLength = len; - } - } - - /** - * Increments estimated byte length of current active log file. - * @param increment additional bytes written to log file. - */ - public void incrementFileLength(int increment) { - synchronized (fileLengthLock) { - fileLength += increment; - } - } - - /** - * Wrapper for OutputStream that will report all write - * operations back to this class for file length calculations. - */ - static class CountingOutputStream extends OutputStream { - /** - * Wrapped output stream. - */ - private final OutputStream os; - - /** - * Rolling file appender to inform of stream writes. - */ - private final RollingFileAppender rfa; - - /** - * Constructor. - * @param os output stream to wrap. - * @param rfa rolling file appender to inform. - */ - public CountingOutputStream( - final OutputStream os, final RollingFileAppender rfa) { - this.os = os; - this.rfa = rfa; - } - - /** - * {@inheritDoc} - */ - public void close() throws IOException { - os.close(); - } - - /** - * {@inheritDoc} - */ - public void flush() throws IOException { - os.flush(); - } - - /** - * {@inheritDoc} - */ - public void write(final byte[] b) throws IOException { - os.write(b); - rfa.incrementFileLength(b.length); - } - - /** - * {@inheritDoc} - */ - public void write(final byte[] b, final int off, final int len) - throws IOException { - os.write(b, off, len); - rfa.incrementFileLength(len); - } - - /** - * {@inheritDoc} - */ - public void write(final int b) throws IOException { - os.write(b); - rfa.incrementFileLength(1); - } - } -} - diff --git a/src/main/java/org/apache/log4j/concurrent/Sync.java b/src/main/java/org/apache/log4j/concurrent/Sync.java deleted file mode 100644 index 18dff6a9d1..0000000000 --- a/src/main/java/org/apache/log4j/concurrent/Sync.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - File: Sync.java - - Originally written by Doug Lea and released into the public domain. - This may be used for any purposes whatsoever without acknowledgment. - Thanks for the assistance and support of Sun Microsystems Labs, - and everyone contributing, testing, and using this code. - - History: - Date Who What - 11Jun1998 dl Create public version - 5Aug1998 dl Added some convenient time constants -*/ - -package org.apache.log4j.concurrent; - -/** - * Main interface for locks, gates, and conditions. - *

    - * Sync objects isolate waiting and notification for particular - * logical states, resource availability, events, and the like that are - * shared across multiple threads. Use of Syncs sometimes - * (but by no means always) adds flexibility and efficiency - * compared to the use of plain java monitor methods - * and locking, and are sometimes (but by no means always) - * simpler to program with. - *

    - * - * Most Syncs are intended to be used primarily (although - * not exclusively) in before/after constructions such as: - *

    - * class X {
    - *   Sync gate;
    - *   // ...
    - *
    - *   public void m() { 
    - *     try {
    - *       gate.acquire();  // block until condition holds
    - *       try {
    - *         // ... method body
    - *       }
    - *       finally {
    - *         gate.release()
    - *       }
    - *     }
    - *     catch (InterruptedException ex) {
    - *       // ... evasive action
    - *     }
    - *   }
    - *
    - *   public void m2(Sync cond) { // use supplied condition
    - *     try {
    - *       if (cond.attempt(10)) {         // try the condition for 10 ms
    - *         try {
    - *           // ... method body
    - *         }
    - *         finally {
    - *           cond.release()
    - *         }
    - *       }
    - *     }
    - *     catch (InterruptedException ex) {
    - *       // ... evasive action
    - *     }
    - *   }
    - * }
    - * 
    - * Syncs may be used in somewhat tedious but more flexible replacements - * for built-in Java synchronized blocks. For example: - *
    - * class HandSynched {          
    - *   private double state_ = 0.0; 
    - *   private final Sync lock;  // use lock type supplied in constructor
    - *   public HandSynched(Sync l) { lock = l; } 
    - *
    - *   public void changeState(double d) {
    - *     try {
    - *       lock.acquire(); 
    - *       try     { state_ = updateFunction(d); } 
    - *       finally { lock.release(); }
    - *     } 
    - *     catch(InterruptedException ex) { }
    - *   }
    - *
    - *   public double getState() {
    - *     double d = 0.0;
    - *     try {
    - *       lock.acquire(); 
    - *       try     { d = accessFunction(state_); }
    - *       finally { lock.release(); }
    - *     } 
    - *     catch(InterruptedException ex){}
    - *     return d;
    - *   }
    - *   private double updateFunction(double d) { ... }
    - *   private double accessFunction(double d) { ... }
    - * }
    - * 
    - * If you have a lot of such methods, and they take a common - * form, you can standardize this using wrappers. Some of these - * wrappers are standardized in LockedExecutor, but you can make others. - * For example: - *
    - * class HandSynchedV2 {          
    - *   private double state_ = 0.0; 
    - *   private final Sync lock;  // use lock type supplied in constructor
    - *   public HandSynchedV2(Sync l) { lock = l; } 
    - *
    - *   protected void runSafely(Runnable r) {
    - *     try {
    - *       lock.acquire();
    - *       try { r.run(); }
    - *       finally { lock.release(); }
    - *     }
    - *     catch (InterruptedException ex) { // propagate without throwing
    - *       Thread.currentThread().interrupt();
    - *     }
    - *   }
    - *
    - *   public void changeState(double d) {
    - *     runSafely(new Runnable() {
    - *       public void run() { state_ = updateFunction(d); } 
    - *     });
    - *   }
    - *   // ...
    - * }
    - * 
    - *

    - * One reason to bother with such constructions is to use deadlock- - * avoiding back-offs when dealing with locks involving multiple objects. - * For example, here is a Cell class that uses attempt to back-off - * and retry if two Cells are trying to swap values with each other - * at the same time. - *

    - * class Cell {
    - *   long value;
    - *   Sync lock = ... // some sync implementation class
    - *   void swapValue(Cell other) {
    - *     for (;;) { 
    - *       try {
    - *         lock.acquire();
    - *         try {
    - *           if (other.lock.attempt(100)) {
    - *             try { 
    - *               long t = value; 
    - *               value = other.value;
    - *               other.value = t;
    - *               return;
    - *             }
    - *             finally { other.lock.release(); }
    - *           }
    - *         }
    - *         finally { lock.release(); }
    - *       } 
    - *       catch (InterruptedException ex) { return; }
    - *     }
    - *   }
    - * }
    - *
    - *

    - * Here is an even fancier version, that uses lock re-ordering - * upon conflict: - *

    - * class Cell { 
    - *   long value;
    - *   Sync lock = ...;
    - *   private static boolean trySwap(Cell a, Cell b) {
    - *     a.lock.acquire();
    - *     try {
    - *       if (!b.lock.attempt(0)) 
    - *         return false;
    - *       try { 
    - *         long t = a.value;
    - *         a.value = b.value;
    - *         b.value = t;
    - *         return true;
    - *       }
    - *       finally { other.lock.release(); }
    - *     }
    - *     finally { lock.release(); }
    - *     return false;
    - *   }
    - *
    - *  void swapValue(Cell other) {
    - *    try {
    - *      while (!trySwap(this, other) &&
    - *            !tryswap(other, this)) 
    - *        Thread.sleep(1);
    - *    }
    - *    catch (InterruptedException ex) { return; }
    - *  }
    - *}
    - *
    - *

    - * Interruptions are in general handled as early as possible. - * Normally, InterruptionExceptions are thrown - * in acquire and attempt(msec) if interruption - * is detected upon entry to the method, as well as in any - * later context surrounding waits. - * However, interruption status is ignored in release(); - *

    - * Timed versions of attempt report failure via return value. - * If so desired, you can transform such constructions to use exception - * throws via - *

    - *   if (!c.attempt(timeval)) throw new TimeoutException(timeval);
    - * 
    - *

    - * The TimoutSync wrapper class can be used to automate such usages. - *

    - * All time values are expressed in milliseconds as longs, which have a maximum - * value of Long.MAX_VALUE, or almost 300,000 centuries. It is not - * known whether JVMs actually deal correctly with such extreme values. - * For convenience, some useful time values are defined as static constants. - *

    - * All implementations of the three Sync methods guarantee to - * somehow employ Java synchronized methods or blocks, - * and so entail the memory operations described in JLS - * chapter 17 which ensure that variables are loaded and flushed - * within before/after constructions. - *

    - * Syncs may also be used in spinlock constructions. Although - * it is normally best to just use acquire(), various forms - * of busy waits can be implemented. For a simple example - * (but one that would probably never be preferable to using acquire()): - *

    - * class X {
    - *   Sync lock = ...
    - *   void spinUntilAcquired() throws InterruptedException {
    - *     // Two phase. 
    - *     // First spin without pausing.
    - *     int purespins = 10; 
    - *     for (int i = 0; i < purespins; ++i) {
    - *       if (lock.attempt(0))
    - *         return true;
    - *     }
    - *     // Second phase - use timed waits
    - *     long waitTime = 1; // 1 millisecond
    - *     for (;;) {
    - *       if (lock.attempt(waitTime))
    - *         return true;
    - *       else 
    - *         waitTime = waitTime * 3 / 2 + 1; // increase 50% 
    - *     }
    - *   }
    - * }
    - * 
    - *

    - * In addition pure synchronization control, Syncs - * may be useful in any context requiring before/after methods. - * For example, you can use an ObservableSync - * (perhaps as part of a LayeredSync) in order to obtain callbacks - * before and after each method invocation for a given class. - *

    - - *

    [ Introduction to this package. ] -**/ - - -public interface Sync { - - /** - * Wait (possibly forever) until successful passage. - * Fail only upon interuption. Interruptions always result in - * `clean' failures. On failure, you can be sure that it has not - * been acquired, and that no - * corresponding release should be performed. Conversely, - * a normal return guarantees that the acquire was successful. - **/ - - public void acquire() throws InterruptedException; - - /** - * Wait at most msecs to pass; report whether passed. - *

    - * The method has best-effort semantics: - * The msecs bound cannot - * be guaranteed to be a precise upper bound on wait time in Java. - * Implementations generally can only attempt to return as soon as possible - * after the specified bound. Also, timers in Java do not stop during garbage - * collection, so timeouts can occur just because a GC intervened. - * So, msecs arguments should be used in - * a coarse-grained manner. Further, - * implementations cannot always guarantee that this method - * will return at all without blocking indefinitely when used in - * unintended ways. For example, deadlocks may be encountered - * when called in an unintended context. - *

    - * @param msecs the number of milleseconds to wait. - * An argument less than or equal to zero means not to wait at all. - * However, this may still require - * access to a synchronization lock, which can impose unbounded - * delay if there is a lot of contention among threads. - * @return true if acquired - **/ - - public boolean attempt(long msecs) throws InterruptedException; - - /** - * Potentially enable others to pass. - *

    - * Because release does not raise exceptions, - * it can be used in `finally' clauses without requiring extra - * embedded try/catch blocks. But keep in mind that - * as with any java method, implementations may - * still throw unchecked exceptions such as Error or NullPointerException - * when faced with uncontinuable errors. However, these should normally - * only be caught by higher-level error handlers. - **/ - - public void release(); - -} - - diff --git a/src/main/java/org/apache/log4j/concurrent/SynchronizedBoolean.java b/src/main/java/org/apache/log4j/concurrent/SynchronizedBoolean.java deleted file mode 100644 index 9e9ebd5de9..0000000000 --- a/src/main/java/org/apache/log4j/concurrent/SynchronizedBoolean.java +++ /dev/null @@ -1,55 +0,0 @@ - -/* - File: SynchronizedBoolean.java - - Originally written by Doug Lea and released into the public domain. - This may be used for any purposes whatsoever without acknowledgment. - Thanks for the assistance and support of Sun Microsystems Labs, - and everyone contributing, testing, and using this code. - - History: - Date Who What - 19Jun1998 dl Create public version -*/ - -package org.apache.log4j.concurrent; - -/** - * A class useful for offloading synch for boolean instance variables. - * A cut down version of the original Doug Lea class. - */ -public final class SynchronizedBoolean { - - private boolean value; - - /** - * Make a new SynchronizedBoolean with the given initial value, - * and using its own internal lock. - **/ - public SynchronizedBoolean(boolean initialValue) { - value = initialValue; - } - - /** - * Return the current value - **/ - public synchronized boolean get() { return value; } - - /** - * Set to newValue. - * @return the old value - **/ - public synchronized boolean set(boolean newValue) { - boolean old = value; - value = newValue; - return old; - } - - /** - * Returns String.valueOf(get())). - */ - public String toString() { return String.valueOf(get()); } - -} - - diff --git a/src/main/java/org/apache/log4j/concurrent/WriterAppender.java b/src/main/java/org/apache/log4j/concurrent/WriterAppender.java deleted file mode 100644 index c2f4d6ee75..0000000000 --- a/src/main/java/org/apache/log4j/concurrent/WriterAppender.java +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.concurrent; - -import org.apache.log4j.spi.LoggingEvent; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import org.apache.log4j.Layout; - -// Contibutors: Jens Uwe Pipka -// Ben Sandee - -/** - WriterAppender appends log events to a {@link java.io.Writer} or an - {@link java.io.OutputStream} depending on the user's choice. - - @author Ceki Gülcü - @author Elias Ross - @since 1.1 */ -public class WriterAppender extends ConcurrentAppender { - - /** - Immediate flush means that the underlying writer or output stream - will be flushed at the end of each append operation. Immediate - flush is slower but ensures that each append request is actually - written. If immediateFlush is set to - false, then there is a good chance that the last few - logs events are not actually written to persistent media if and - when the application crashes. - -

    The immediateFlush variable is set to - true by default. - - */ - protected boolean immediateFlush = true; - - /** - The encoding to use when opening an InputStream.

    The - encoding variable is set to null by - default which results in the utilization of the system's default - encoding. */ - protected String encoding; - - /** - * This is the {@link Writer Writer} where we will write to. - * Do not directly use this object without obtaining a write lock. - */ - protected Writer writer; - - /** - * The default constructor does nothing. - * */ - public WriterAppender() { - super(false); - } - - /** - If the ImmediateFlush option is set to - true, the appender will flush at the end of each - write. This is the default behavior. If the option is set to - false, then the underlying stream can defer writing - to physical medium to a later time. - -

    Avoiding the flush operation at the end of each append results in - a performance gain of 10 to 20 percent. However, there is safety - tradeoff involved in skipping flushing. Indeed, when flushing is - skipped, then it is likely that the last few log events will not - be recorded on disk when the application exits. This is a high - price to pay even for a 20% performance gain. - */ - public void setImmediateFlush(boolean value) { - immediateFlush = value; - } - - /** - Returns value of the ImmediateFlush option. - */ - public boolean getImmediateFlush() { - return immediateFlush; - } - - /** - * Activates options. Should be called only once. - */ - public void activateOptions() { - - if (getLayout() == null) { - getLogger().error( - "No layout set for the appender named [{}].", name); - return; - } - - if (this.writer == null) { - getLogger().error( - "No writer set for the appender named [{}].", name); - return; - } - - active.set(true); - - } - - /** - This method is called by the {@link AppenderSkeleton#doAppend} - method. - -

    If the output stream exists and is writable then write a log - statement to the output stream. Otherwise, write a single warning - message to System.err. - -

    The format of the output will depend on this appender's - layout. - - */ - public void append(LoggingEvent event) { - subAppend(event); - } - - /** - Close this appender instance. The underlying stream or writer is - also closed. -

    Closed appenders cannot be reused. - */ - protected void internalClose() { - closeWriter(); - } - - /** - * Close the underlying {@link java.io.Writer}. - */ - protected void closeWriter() { - try { - lock.writeLock().acquire(); - } catch (InterruptedException e) { - getLogger().warn("interrupted", e); - } - try { - closeWriter0(); - } finally { - lock.writeLock().release(); - } - } - - /** - * Closes with no locks held. - */ - private void closeWriter0() { - if (this.writer == null) - return; - try { - // before closing we have to output the footer - writeFooter(); - this.writer.close(); - this.writer = null; - } catch (IOException e) { - getLogger().error("Could not close writer for WriterAppener named "+name, e); - } - } - - /** - Returns an OutputStreamWriter when passed an OutputStream. The - encoding used will depend on the value of the - encoding property. If the encoding value is - specified incorrectly the writer will be opened using the default - system encoding (an error message will be printed to the loglog. */ - protected OutputStreamWriter createWriter(OutputStream os) { - OutputStreamWriter retval = null; - - String enc = getEncoding(); - - if (enc != null) { - try { - retval = new OutputStreamWriter(os, enc); - } catch (IOException e) { - getLogger().warn("Error initializing output writer."); - getLogger().warn("Unsupported encoding?"); - } - } - - if (retval == null) { - retval = new OutputStreamWriter(os); - } - - return retval; - } - - public String getEncoding() { - return encoding; - } - - public void setEncoding(String value) { - encoding = value; - } - - /** -

    Sets the Writer where the log output will go. The - specified Writer must be opened by the user and be - writable. - -

    The java.io.Writer will be closed when the - appender instance is closed. - - -

    WARNING: Logging to an unopened Writer will fail. -

    - @param writer An already opened Writer. */ - public void setWriter(Writer writer) { - // close any previously opened writer - try { - lock.writeLock().acquire(); - } catch (InterruptedException e) { - getLogger().warn("interrupted", e); - return; - } - try { - closeWriter0(); - this.writer = writer; - writeHeader(); - } finally { - lock.writeLock().release(); - } - } - - /** - * Actual writing occurs here. - *

    Most subclasses of WriterAppender will need to override - * this method. - */ - protected void subAppend(LoggingEvent event) { - try { - - // Format first - Layout layout = getLayout(); - String se = layout.format(event); - String st[] = null; - if (layout.ignoresThrowable()) { - st = event.getThrowableStrRep(); - } - - // Write as one message - synchronized (this.writer) { - this.writer.write(se); - if (st != null) { - int len = st.length; - for (int i = 0; i < len; i++) { - this.writer.write(st[i]); - this.writer.write(Layout.LINE_SEP); - } - } - } - - if (this.immediateFlush) - this.writer.flush(); - - } catch (IOException ioe) { - boolean wasOrder = active.set(false); - if (wasOrder) { - getLogger().error("IO failure for appender named "+name, ioe); - } - } - } - - /** - The WriterAppender requires a layout. Hence, this method returns - true. - */ - public boolean requiresLayout() { - return true; - } - - /** - * Write a footer as produced by the embedded layout's {@link - * Layout#getFooter} method. - */ - protected void writeFooter() { - Layout layout = getLayout(); - if (layout != null) { - String f = layout.getFooter(); - - if ((f != null) && (this.writer != null)) { - try { - this.writer.write(f); - } catch(IOException ioe) { - active.set(false); - getLogger().error("Failed to write footer for Appender named "+name, ioe); - } - } - } - } - - /** - * Write a header as produced by the embedded layout's {@link - * Layout#getHeader} method. - */ - protected void writeHeader() { - Layout layout = getLayout(); - if (layout != null) { - String h = layout.getHeader(); - - if ((h != null) && (this.writer != null)) { - try { - this.writer.write(h); - this.writer.flush(); - } catch(IOException ioe) { - active.set(false); - getLogger().error("Failed to write header for WriterAppender named "+name, ioe); - } - } - } - } - - -} - diff --git a/src/main/java/org/apache/log4j/concurrent/WriterPreferenceReadWriteLock.java b/src/main/java/org/apache/log4j/concurrent/WriterPreferenceReadWriteLock.java deleted file mode 100644 index 00dfebad3f..0000000000 --- a/src/main/java/org/apache/log4j/concurrent/WriterPreferenceReadWriteLock.java +++ /dev/null @@ -1,312 +0,0 @@ -/* - File: WriterPreferenceReadWriteLock.java - - Originally written by Doug Lea and released into the public domain. - This may be used for any purposes whatsoever without acknowledgment. - Thanks for the assistance and support of Sun Microsystems Labs, - and everyone contributing, testing, and using this code. - - History: - Date Who What - 11Jun1998 dl Create public version - 5Aug1998 dl replaced int counters with longs - 25aug1998 dl record writer thread - 3May1999 dl add notifications on interrupt/timeout - -*/ - -package org.apache.log4j.concurrent; - -/** - * A ReadWriteLock that prefers waiting writers over - * waiting readers when there is contention. This class - * is adapted from the versions described in CPJ, improving - * on the ones there a bit by segregating reader and writer - * wait queues, which is typically more efficient. - *

    - * The locks are NOT reentrant. In particular, - * even though it may appear to usually work OK, - * a thread holding a read lock should not attempt to - * re-acquire it. Doing so risks lockouts when there are - * also waiting writers. - *

    [ Introduction to this package. ] - **/ - -class WriterPreferenceReadWriteLock implements ReadWriteLock { - - protected long activeReaders_ = 0; - protected Thread activeWriter_ = null; - protected long waitingReaders_ = 0; - protected long waitingWriters_ = 0; - - - protected final ReaderLock readerLock_ = new ReaderLock(); - protected final WriterLock writerLock_ = new WriterLock(); - - public Sync writeLock() { return writerLock_; } - public Sync readLock() { return readerLock_; } - - /* - A bunch of small synchronized methods are needed - to allow communication from the Lock objects - back to this object, that serves as controller - */ - - - protected synchronized void cancelledWaitingReader() { --waitingReaders_; } - protected synchronized void cancelledWaitingWriter() { --waitingWriters_; } - - - /** Override this method to change to reader preference **/ - protected boolean allowReader() { - return activeWriter_ == null && waitingWriters_ == 0; - } - - - protected synchronized boolean startRead() { - boolean allowRead = allowReader(); - if (allowRead) ++activeReaders_; - return allowRead; - } - - protected synchronized boolean startWrite() { - - // The allowWrite expression cannot be modified without - // also changing startWrite, so is hard-wired - - boolean allowWrite = (activeWriter_ == null && activeReaders_ == 0); - if (allowWrite) activeWriter_ = Thread.currentThread(); - return allowWrite; - } - - - /* - Each of these variants is needed to maintain atomicity - of wait counts during wait loops. They could be - made faster by manually inlining each other. We hope that - compilers do this for us though. - */ - - protected synchronized boolean startReadFromNewReader() { - boolean pass = startRead(); - if (!pass) ++waitingReaders_; - return pass; - } - - protected synchronized boolean startWriteFromNewWriter() { - boolean pass = startWrite(); - if (!pass) ++waitingWriters_; - return pass; - } - - protected synchronized boolean startReadFromWaitingReader() { - boolean pass = startRead(); - if (pass) --waitingReaders_; - return pass; - } - - protected synchronized boolean startWriteFromWaitingWriter() { - boolean pass = startWrite(); - if (pass) --waitingWriters_; - return pass; - } - - /** - * Called upon termination of a read. - * Returns the object to signal to wake up a waiter, or null if no such - **/ - protected synchronized Signaller endRead() { - if (--activeReaders_ == 0 && waitingWriters_ > 0) - return writerLock_; - else - return null; - } - - - /** - * Called upon termination of a write. - * Returns the object to signal to wake up a waiter, or null if no such - **/ - protected synchronized Signaller endWrite() { - activeWriter_ = null; - if (waitingReaders_ > 0 && allowReader()) - return readerLock_; - else if (waitingWriters_ > 0) - return writerLock_; - else - return null; - } - - - /** - * Reader and Writer requests are maintained in two different - * wait sets, by two different objects. These objects do not - * know whether the wait sets need notification since they - * don't know preference rules. So, each supports a - * method that can be selected by main controlling object - * to perform the notifications. This base class simplifies mechanics. - **/ - - protected abstract class Signaller { // base for ReaderLock and WriterLock - abstract void signalWaiters(); - } - - protected class ReaderLock extends Signaller implements Sync { - - public void acquire() throws InterruptedException { - if (Thread.interrupted()) throw new InterruptedException(); - InterruptedException ie = null; - synchronized(this) { - if (!startReadFromNewReader()) { - for (;;) { - try { - ReaderLock.this.wait(); - if (startReadFromWaitingReader()) - return; - } - catch(InterruptedException ex){ - cancelledWaitingReader(); - ie = ex; - break; - } - } - } - } - if (ie != null) { - // fall through outside synch on interrupt. - // This notification is not really needed here, - // but may be in plausible subclasses - writerLock_.signalWaiters(); - throw ie; - } - } - - - public void release() { - Signaller s = endRead(); - if (s != null) s.signalWaiters(); - } - - - synchronized void signalWaiters() { ReaderLock.this.notifyAll(); } - - public boolean attempt(long msecs) throws InterruptedException { - if (Thread.interrupted()) throw new InterruptedException(); - InterruptedException ie = null; - synchronized(this) { - if (msecs <= 0) - return startRead(); - else if (startReadFromNewReader()) - return true; - else { - long waitTime = msecs; - long start = System.currentTimeMillis(); - for (;;) { - try { ReaderLock.this.wait(waitTime); } - catch(InterruptedException ex){ - cancelledWaitingReader(); - ie = ex; - break; - } - if (startReadFromWaitingReader()) - return true; - else { - waitTime = msecs - (System.currentTimeMillis() - start); - if (waitTime <= 0) { - cancelledWaitingReader(); - break; - } - } - } - } - } - // safeguard on interrupt or timeout: - writerLock_.signalWaiters(); - if (ie != null) throw ie; - else return false; // timed out - } - - } - - protected class WriterLock extends Signaller implements Sync { - - public void acquire() throws InterruptedException { - if (Thread.interrupted()) throw new InterruptedException(); - InterruptedException ie = null; - synchronized(this) { - if (!startWriteFromNewWriter()) { - for (;;) { - try { - WriterLock.this.wait(); - if (startWriteFromWaitingWriter()) - return; - } - catch(InterruptedException ex){ - cancelledWaitingWriter(); - WriterLock.this.notify(); - ie = ex; - break; - } - } - } - } - if (ie != null) { - // Fall through outside synch on interrupt. - // On exception, we may need to signal readers. - // It is not worth checking here whether it is strictly necessary. - readerLock_.signalWaiters(); - throw ie; - } - } - - public void release(){ - Signaller s = endWrite(); - if (s != null) s.signalWaiters(); - } - - synchronized void signalWaiters() { WriterLock.this.notify(); } - - public boolean attempt(long msecs) throws InterruptedException { - if (Thread.interrupted()) throw new InterruptedException(); - InterruptedException ie = null; - synchronized(this) { - if (msecs <= 0) - return startWrite(); - else if (startWriteFromNewWriter()) - return true; - else { - long waitTime = msecs; - long start = System.currentTimeMillis(); - for (;;) { - try { WriterLock.this.wait(waitTime); } - catch(InterruptedException ex){ - cancelledWaitingWriter(); - WriterLock.this.notify(); - ie = ex; - break; - } - if (startWriteFromWaitingWriter()) - return true; - else { - waitTime = msecs - (System.currentTimeMillis() - start); - if (waitTime <= 0) { - cancelledWaitingWriter(); - WriterLock.this.notify(); - break; - } - } - } - } - } - - readerLock_.signalWaiters(); - if (ie != null) throw ie; - else return false; // timed out - } - - } - - - -} - diff --git a/src/main/java/org/apache/log4j/concurrent/package.html b/src/main/java/org/apache/log4j/concurrent/package.html deleted file mode 100644 index b0bd0ba83c..0000000000 --- a/src/main/java/org/apache/log4j/concurrent/package.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - Concurrent - - - - -

    Concurrent appenders

    - -

    - Mostly compatible replacement appenders for the existing Log4J appenders - which have a potential for deadlock when used in certain ways. The locking design allows - for multiple threads to execute {@link org.apache.log4j.Appender#doAppend()} - simultaneously. - Locking is done using a {@link org.apache.log4j.concurrent.ReadWriteLock} interface - instead of synchronized blocks. -

    - -

    - The {@link org.apache.log4j.concurrent.ConcurrentAppender} derived appenders - are almost identical in code to ones found in the parent package, - except in places where locking is used. -

    - -

    - Users wishing to create their own concurrent appender should follow - the source for {@link org.apache.log4j.concurrent.WriterAppender}, which - demonstrates how to properly guard critical sections. -

    - - - \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/config/ConfigWatchdog.java b/src/main/java/org/apache/log4j/config/ConfigWatchdog.java deleted file mode 100644 index 9d3f97ac39..0000000000 --- a/src/main/java/org/apache/log4j/config/ConfigWatchdog.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.config; - -import org.apache.log4j.spi.LoggerRepository; - -/** - Defines the basic interface that all ConfigWatchdogs must support. - -

    ConfigWatchdogs "watch" a log4j configuration source, and when - new, changed configuration data is available, the watchdog will - initiate a reconfiguration of the log4j settings using the new - configuration data. - -

    All watchdogs can have a name and configurator class. - The configurator class will be used when reconfiguring using the - new data. All watchdogs can be started and stopped. - -

    Several different ConfigWatchdog classes are available in the - org.apache.log4j.config package, such as FileWatchdog (watches a - configuration file), HttpWatchdog (watches a configuration file - at a url location), and SocketWatchdog (watches a socket for - incoming configuration data). - -

    If these are not sufficient, developers are encouraged - to implement specific versions of ConfigWatchdogs for their - particular needs. This can be done by subclassing the WatchdogBase - or URLWatchdogBase abstract classes, or to write their own class - that implements the ConfigWatchdog interface. Please see the - above mentioned classes for more information. - - @author Mark Womack - - @since 1.3 -*/ -public interface ConfigWatchdog { - - /** - Returns true if this watchdog is currently running. */ - public boolean isRunning(); - - /** - Set the name of this watchdog. The name is used by other - components to identify this watchdog. */ - public void setName(String name); - - /** - Get the name of this watchdog. The name uniquely identifies - the watchdog. */ - public String getName(); - - /** - Sets the configurator class name used for reconfiguration. */ - public void setConfiguratorClassName(String className); - - /** - Gets the configurator class name used for reconfiguration. */ - public String getConfiguratorClassName(); - - /** - Sets the configurator class used for reconfiguration. */ - public void setConfiguratorClass(Class clazz); - - /** - Gets the configurator class used for reconfiguration. */ - public Class getConfiguratorClass(); - - /** - Set the logger repository this watchdog will reconfigure - when new configuration data is detected. If not set, - should default to the return value of - LogManager.getLoggerRepository(). */ - public void setLoggerRepository(LoggerRepository repository); - - /** - Get the logger repository this watchdog will reconfigure - when new configuration data is detected. Default is the - return value of LogManager.getLoggerRepository(). */ - public LoggerRepository getLoggerRepository(); - - /** - Starts this watchdog watching. After calling this method the - watchdog will be active. */ - public void startWatching(); - - /** - Stops this watchdog. After calling this method the - watchdog will become inactive, but it is not guaranteed - to be immediately inactive. If threads are involved in the - implementation, it may take time for them to be interupted and - exited. */ - public void stopWatching(); -} diff --git a/src/main/java/org/apache/log4j/config/ConfiguratorBase.java b/src/main/java/org/apache/log4j/config/ConfiguratorBase.java deleted file mode 100644 index bcb86df790..0000000000 --- a/src/main/java/org/apache/log4j/config/ConfiguratorBase.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Created on Nov 17, 2004 - * - * To change the template for this generated file go to - * Window>Preferences>Java>Code Generation>Code and Comments - */ -package org.apache.log4j.config; - -import java.util.List; - -import org.apache.log4j.Appender; -import org.apache.log4j.ConsoleAppender; -import org.apache.log4j.Logger; -import org.apache.log4j.PatternLayout; -import org.apache.log4j.helpers.Constants; -import org.apache.log4j.spi.Configurator; -import org.apache.log4j.spi.ErrorItem; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.varia.ListAppender; - - -/** - * Code useful to most configurators. - * - * @author Ceki Gulcu - * @since 1.3 - */ -abstract public class ConfiguratorBase implements Configurator { - - /** - * Defining this value makes log4j print log4j-internal debug statements. - *

    - * The value of this string is log4j.debug. - * - *

    Note that the search for all option names is case sensitive. - * */ - public static final String DEBUG_KEY = "log4j.debug"; - - protected Logger getLogger(LoggerRepository repository) { - return repository.getLogger(this.getClass().getName()); - } - - protected void addError(ErrorItem errorItem) { - getErrorList().add(errorItem); - } - - abstract public List getErrorList(); - - /** - * Attach a list appender which will be used to collect the logging events - * generated by log4j components, including this JoranConfigurator. These - * events will later be output when {@link #detachListAppender} method - * is called. - * - * @param repository - */ - protected void attachListAppender(LoggerRepository repository) { - Logger ll = repository.getLogger(Constants.LOG4J_PACKAGE_NAME); - Appender appender = new ListAppender(); - appender.setName(Constants.TEMP_LIST_APPENDER_NAME); - ll.addAppender(appender); - ll.setAdditivity(false); - } - - /** - * Output the previously collected events using the current log4j - * configuration. When that is completed, cluse and detach the - * ListAppender previously created by {@link #attachListAppender}. - * - * @param repository - */ - protected void detachListAppender(LoggerRepository repository) { - - Logger ll = repository.getLogger(Constants.LOG4J_PACKAGE_NAME); - - // FIXME: What happens if the users wanted to set the additivity flag - // for "org.apahce.log4j" to false in the config file? We are now - // potentially overriding her wishes but I don't see any other way. - ll.setAdditivity(true); - - ListAppender listAppender = (ListAppender) ll.getAppender(Constants.TEMP_LIST_APPENDER_NAME); - if(listAppender == null) { - String errMsg = "Could not find appender "+Constants.TEMP_LIST_APPENDER_NAME; - getLogger(repository).error(errMsg); - addError(new ErrorItem(errMsg)); - return; - } - - List eventList = listAppender.getList(); - int size = eventList.size(); - for(int i = 0; i < size; i++) { - LoggingEvent event = (LoggingEvent) eventList.get(i); - Logger xLogger = event.getLogger(); - if (event.getLevel().isGreaterOrEqual(xLogger.getEffectiveLevel())) { - xLogger.callAppenders(event); - } - } - listAppender.clearList(); - listAppender.close(); - ll.removeAppender(listAppender); - } - - static public void attachTemporaryConsoleAppender(LoggerRepository repository) { - Logger ll = repository.getLogger(Constants.LOG4J_PACKAGE_NAME); - - ConsoleAppender appender = new ConsoleAppender(); - appender.setLayout( - new PatternLayout("LOG4J-INTERNAL: %d %level [%t] %c#%M:%L)- %m%n")); - appender.setName(Constants.TEMP_CONSOLE_APPENDER_NAME); - appender.activateOptions(); - ll.addAppender(appender); - } - - static public void detachTemporaryConsoleAppender(LoggerRepository repository, List errorList) { - - Logger ll = repository.getLogger(Constants.LOG4J_PACKAGE_NAME); - ConsoleAppender consoleAppender = - (ConsoleAppender) ll.getAppender(Constants.TEMP_CONSOLE_APPENDER_NAME); - if (consoleAppender == null) { - String errMsg = - "Could not find appender " + Constants.TEMP_CONSOLE_APPENDER_NAME; - errorList.add(new ErrorItem(errMsg)); - return; - } - consoleAppender.close(); - ll.removeAppender(consoleAppender); - } - - /** - * Dump any errors on System.out. - */ - public void dumpErrors() { - List errorList = getErrorList(); - for(int i = 0; i < errorList.size(); i++) { - ErrorItem ei = (ErrorItem) errorList.get(i); - ei.dump(System.out); - } - } - -} diff --git a/src/main/java/org/apache/log4j/config/PropertyGetter.java b/src/main/java/org/apache/log4j/config/PropertyGetter.java index 6f116e3990..48053765ed 100644 --- a/src/main/java/org/apache/log4j/config/PropertyGetter.java +++ b/src/main/java/org/apache/log4j/config/PropertyGetter.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,12 +17,16 @@ package org.apache.log4j.config; -import org.apache.log4j.Level; -import org.apache.log4j.spi.ComponentBase; +import org.apache.log4j.Priority; +import org.apache.log4j.helpers.LogLog; -import java.beans.*; - -import java.lang.reflect.*; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.io.InterruptedIOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; /** @@ -29,11 +34,15 @@ @author Anders Kristensen */ -public class PropertyGetter extends ComponentBase { - protected static final Object[] NULL_ARG = new Object[] { }; +public class PropertyGetter { + protected static final Object[] NULL_ARG = new Object[] {}; protected Object obj; protected PropertyDescriptor[] props; + public interface PropertyCallback { + void foundProperty(Object obj, String prefix, String name, Object value); + } + /** Create a new PropertyGetter for the specified Object. This is done in prepartion for invoking {@link @@ -41,53 +50,61 @@ public class PropertyGetter extends ComponentBase { more times. @param obj the object for which to set properties */ - public PropertyGetter(Object obj) throws IntrospectionException { + public + PropertyGetter(Object obj) throws IntrospectionException { BeanInfo bi = Introspector.getBeanInfo(obj.getClass()); props = bi.getPropertyDescriptors(); this.obj = obj; } - public static void getProperties( - Object obj, PropertyCallback callback, String prefix) { + public + static + void getProperties(Object obj, PropertyCallback callback, String prefix) { try { new PropertyGetter(obj).getProperties(callback, prefix); } catch (IntrospectionException ex) { - //LogLog.error("Failed to introspect object " + obj, ex); + LogLog.error("Failed to introspect object " + obj, ex); } } - public void getProperties(PropertyCallback callback, String prefix) { + public + void getProperties(PropertyCallback callback, String prefix) { for (int i = 0; i < props.length; i++) { Method getter = props[i].getReadMethod(); if (getter == null) { continue; - } - String name = props[i].getName(); + } if (!isHandledType(getter.getReturnType())) { - getLogger().warn("Ignoring " + name +" " + getter.getReturnType()); - continue; + //System.err.println("Ignoring " + props[i].getName() +" " + getter.getReturnType()); + continue; } + String name = props[i].getName(); try { - Object result = getter.invoke(obj, NULL_ARG); - - getLogger().debug("PROP " + name +": " + result); - if (result != null) { - callback.foundProperty(obj, prefix, name, result); + Object result = getter.invoke(obj, NULL_ARG); + //System.err.println("PROP " + name +": " + result); + if (result != null) { + callback.foundProperty(obj, prefix, name, result); + } + } catch (IllegalAccessException ex) { + LogLog.warn("Failed to get value of property " + name); + } catch (InvocationTargetException ex) { + if (ex.getTargetException() instanceof InterruptedException + || ex.getTargetException() instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); } - } catch (Exception e) { - getLogger().warn("Failed to get value of property " + name, e); + LogLog.warn("Failed to get value of property " + name); + } catch (RuntimeException ex) { + LogLog.warn("Failed to get value of property " + name); } } } - protected boolean isHandledType(Class type) { - return String.class.isAssignableFrom(type) - || Integer.TYPE.isAssignableFrom(type) || Long.TYPE.isAssignableFrom(type) - || Boolean.TYPE.isAssignableFrom(type) - || Level.class.isAssignableFrom(type); - } - - public interface PropertyCallback { - void foundProperty(Object obj, String prefix, String name, Object value); + protected + boolean isHandledType(Class type) { + return String.class.isAssignableFrom(type) || + Integer.TYPE.isAssignableFrom(type) || + Long.TYPE.isAssignableFrom(type) || + Boolean.TYPE.isAssignableFrom(type) || + Priority.class.isAssignableFrom(type); } } diff --git a/src/main/java/org/apache/log4j/config/PropertyPrinter.java b/src/main/java/org/apache/log4j/config/PropertyPrinter.java index 1ed7b6290f..9a62d530b7 100644 --- a/src/main/java/org/apache/log4j/config/PropertyPrinter.java +++ b/src/main/java/org/apache/log4j/config/PropertyPrinter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -17,6 +18,7 @@ package org.apache.log4j.config; import org.apache.log4j.Appender; +import org.apache.log4j.Category; import org.apache.log4j.Level; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; @@ -27,7 +29,7 @@ /** Prints the configuration of the log4j default hierarchy - (which needs to be auto-initialized) as a properties file + (which needs to be auto-initialized) as a propoperties file on a {@link PrintWriter}. @author Anders Kristensen @@ -64,10 +66,14 @@ String genAppName() { */ protected boolean isGenAppName(String name) { - if (name.length() < 2 || name.charAt(0) != 'A') return false; + if (name.length() < 2 || name.charAt(0) != 'A') { + return false; + } for (int i = 0; i < name.length(); i++) { - if (name.charAt(i) < '0' || name.charAt(i) > '9') return false; + if (name.charAt(i) < '0' || name.charAt(i) > '9') { + return false; + } } return true; } @@ -88,8 +94,11 @@ void print(PrintWriter out) { } } + /** + * @since 1.2.15 + */ protected - void printOptions(PrintWriter out, Logger cat) { + void printOptions(PrintWriter out, Category cat) { Enumeration appenders = cat.getAllAppenders(); Level prio = cat.getLevel(); String appenderString = (prio == null ? "" : prio.toString()); @@ -121,7 +130,11 @@ void printOptions(PrintWriter out, Logger cat) { } if (!cat.getAdditivity() && cat != Logger.getRootLogger()) { out.println("log4j.additivity." + cat.getName() + "=false"); - } + } + } + + protected void printOptions(PrintWriter out, Logger cat) { + printOptions(out, (Category) cat); } protected diff --git a/src/main/java/org/apache/log4j/config/PropertySetter.java b/src/main/java/org/apache/log4j/config/PropertySetter.java index 84ef125969..dae3c00746 100644 --- a/src/main/java/org/apache/log4j/config/PropertySetter.java +++ b/src/main/java/org/apache/log4j/config/PropertySetter.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,32 +16,34 @@ */ // Contributors: Georg Lundesgaard + package org.apache.log4j.config; import org.apache.log4j.Appender; import org.apache.log4j.Level; import org.apache.log4j.Priority; +import org.apache.log4j.helpers.LogLog; import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.spi.ComponentBase; import org.apache.log4j.spi.OptionHandler; +import org.apache.log4j.spi.ErrorHandler; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; -import java.beans.MethodDescriptor; import java.beans.PropertyDescriptor; +import java.io.InterruptedIOException; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Enumeration; import java.util.Properties; - /** General purpose Object property setter. Clients repeatedly invokes {@link #setProperty setProperty(name,value)} in order to invoke setters on the Object specified in the constructor. This class relies on the JavaBeans {@link Introspector} to analyze the given Object Class using reflection. - +

    Usage:

          PropertySetter ps = new PropertySetter(anObject);
    @@ -51,322 +54,222 @@
        will cause the invocations anObject.setName("Joe"), anObject.setAge(32),
        and setMale(true) if such methods exist with those signatures.
        Otherwise an {@link IntrospectionException} are thrown.
    -
    +  
        @author Anders Kristensen
        @since 1.1
      */
    -public class PropertySetter extends ComponentBase {
    -  public static final int NOT_FOUND = 0;
    -  public static final int AS_PROPERTY = 1;
    -  public static final int AS_COLLECTION = 2;
    +public class PropertySetter {
       protected Object obj;
    -  protected Class objClass;
       protected PropertyDescriptor[] props;
    -  protected MethodDescriptor[] methodDescriptors;
    -
    +  
       /**
         Create a new PropertySetter for the specified Object. This is done
         in prepartion for invoking {@link #setProperty} one or more times.
    -
    +    
         @param obj  the object for which to set properties
        */
    -  public PropertySetter(Object obj) {
    +  public
    +  PropertySetter(Object obj) {
         this.obj = obj;
    -    this.objClass = obj.getClass();
       }
    -
    +  
       /**
          Uses JavaBeans {@link Introspector} to computer setters of object to be
          configured.
        */
    -  protected void introspect() {
    -    Class c = obj.getClass();
    -    getLogger().debug("introspect " + c);
    +  protected
    +  void introspect() {
         try {
    -      BeanInfo bi = Introspector.getBeanInfo(c);
    +      BeanInfo bi = Introspector.getBeanInfo(obj.getClass());
           props = bi.getPropertyDescriptors();
    -      StringBuffer sb = new StringBuffer();
    -      for (int i = 0; i < props.length; i++) {
    -        PropertyDescriptor d = props[i];
    -        String rw = (d.getWriteMethod() == null) ? "(ro)" : "";
    -        sb.append(" ").append(d.getName()).append(rw);
    -      }
    -      getLogger().debug(c + " properties: " + sb);
    -      
    -      methodDescriptors = bi.getMethodDescriptors();
         } catch (IntrospectionException ex) {
    -      getLogger().error(
    -        "Failed to introspect " + c + ": " + ex.getMessage());
    +      LogLog.error("Failed to introspect "+obj+": " + ex.getMessage());
           props = new PropertyDescriptor[0];
    -      methodDescriptors = new MethodDescriptor[0];
         }
       }
    +  
     
    -    /**
    -       Set the properties of an object passed as a parameter in one
    -       go. The properties are parsed relative to a
    -       prefix.
    -
    -       @param obj The object to configure.
    -       @param properties A java.util.Properties containing keys and values.
    -       @param prefix Only keys having the specified prefix will be set.
    -     @deprecated
    -    */
    -    public
    -    static
    -    void setProperties(Object obj, Properties properties, String prefix) {
    -      new PropertySetter(obj).setProperties(properties, prefix);
    -    }
    +  /**
    +     Set the properties of an object passed as a parameter in one
    +     go. The properties are parsed relative to a
    +     prefix.
     
    +     @param obj The object to configure.
    +     @param properties A java.util.Properties containing keys and values.
    +     @param prefix Only keys having the specified prefix will be set.
    +  */
    +  public
    +  static
    +  void setProperties(Object obj, Properties properties, String prefix) {
    +    new PropertySetter(obj).setProperties(properties, prefix);
    +  }
    +  
     
       /**
    -   * Set the properites for the object that match the prefix 
    -   * passed as parameter.
    +     Set the properites for the object that match the
    +     prefix passed as parameter.
    +
    +     
        */
    -  public void setProperties(Properties properties, String prefix) {
    +  public
    +  void setProperties(Properties properties, String prefix) {
         int len = prefix.length();
    -
    -    for (Enumeration e = properties.propertyNames(); e.hasMoreElements();) {
    +    
    +    for (Enumeration e = properties.propertyNames(); e.hasMoreElements(); ) {
           String key = (String) e.nextElement();
    -
    +      
           // handle only properties that start with the desired frefix.
           if (key.startsWith(prefix)) {
    -        // ignore key if it contains dots after the prefix
    -        if (key.indexOf('.', len + 1) > 0) {
    -          //System.err.println("----------Ignoring---["+key
    -          //	     +"], prefix=["+prefix+"].");
    -          continue;
    -        }
     
    -        String value = OptionConverter.findAndSubst(key, properties);
    +	
    +	// ignore key if it contains dots after the prefix
    +        if (key.indexOf('.', len + 1) > 0) {
    +	  //System.err.println("----------Ignoring---["+key
    +	  //	     +"], prefix=["+prefix+"].");
    +	  continue;
    +	}
             
    +	String value = OptionConverter.findAndSubst(key, properties);
             key = key.substring(len);
    -
    -        if ("layout".equals(key) && obj instanceof Appender) {
    +        if (("layout".equals(key) || "errorhandler".equals(key)) && obj instanceof Appender) {
               continue;
             }
    +        //
    +        //   if the property type is an OptionHandler
    +        //     (for example, triggeringPolicy of org.apache.log4j.rolling.RollingFileAppender)
    +        PropertyDescriptor prop = getPropertyDescriptor(Introspector.decapitalize(key));
    +        if (prop != null
    +                && OptionHandler.class.isAssignableFrom(prop.getPropertyType())
    +                && prop.getWriteMethod() != null) {
    +            OptionHandler opt = (OptionHandler)
    +                    OptionConverter.instantiateByKey(properties, prefix + key,
    +                                  prop.getPropertyType(),
    +                                  null);
    +            PropertySetter setter = new PropertySetter(opt);
    +            setter.setProperties(properties, prefix + key + ".");
    +            try {
    +                prop.getWriteMethod().invoke(this.obj, new Object[] { opt });
    +            } catch(IllegalAccessException ex) {
    +                LogLog.warn("Failed to set property [" + key +
    +                            "] to value \"" + value + "\". ", ex);
    +            } catch(InvocationTargetException ex) {
    +                if (ex.getTargetException() instanceof InterruptedException
    +                        || ex.getTargetException() instanceof InterruptedIOException) {
    +                    Thread.currentThread().interrupt();
    +                }
    +                LogLog.warn("Failed to set property [" + key +
    +                            "] to value \"" + value + "\". ", ex);
    +            } catch(RuntimeException ex) {
    +                LogLog.warn("Failed to set property [" + key +
    +                            "] to value \"" + value + "\". ", ex);
    +            }
    +            continue;
    +        }
     
             setProperty(key, value);
           }
         }
    +    activate();
       }
    -
    +  
       /**
          Set a property on this PropertySetter's Object. If successful, this
          method will invoke a setter method on the underlying Object. The
          setter is the one for the specified property name and the value is
          determined partly from the setter argument type and partly from the
          value specified in the call to this method.
    -
    +     
          

    If the setter expects a String no conversion is necessary. If it expects an int, then an attempt is made to convert 'value' to an int using new Integer(value). If the setter expects a boolean, the conversion is by new Boolean(value). - + @param name name of the property @param value String value of the property */ - public void setProperty(String name, String value) { + public + void setProperty(String name, String value) { if (value == null) { - return; + return; } - + name = Introspector.decapitalize(name); - PropertyDescriptor prop = getPropertyDescriptor(name); - + //LogLog.debug("---------Key: "+name+", type="+prop.getPropertyType()); + if (prop == null) { - getLogger().warn( - "No such property [" + name + "] in " + objClass.getName() + "."); + LogLog.warn("No such property [" + name + "] in "+ + obj.getClass().getName()+"." ); } else { try { setProperty(prop, name, value); } catch (PropertySetterException ex) { - getLogger().warn( - "Failed to set property [" + name + "] to value \"" + value + "\". ", - ex.rootCause != null ? ex.rootCause : ex); + LogLog.warn("Failed to set property [" + name + + "] to value \"" + value + "\". ", ex.rootCause); } } } - - /** + + /** Set the named property given a {@link PropertyDescriptor}. @param prop A PropertyDescriptor describing the characteristics of the property to set. @param name The named of the property to set. - @param value The value of the property. + @param value The value of the property. */ - public void setProperty(PropertyDescriptor prop, String name, String value) + public + void setProperty(PropertyDescriptor prop, String name, String value) throws PropertySetterException { Method setter = prop.getWriteMethod(); - if (setter == null) { - throw new PropertySetterException( - "No setter for property [" + name + "]."); + throw new PropertySetterException("No setter for property ["+name+"]."); } - Class[] paramTypes = setter.getParameterTypes(); - if (paramTypes.length != 1) { throw new PropertySetterException("#params for setter != 1"); } - + Object arg; - try { arg = convertArg(value, paramTypes[0]); } catch (Throwable t) { - throw new PropertySetterException( - "Conversion to type [" + paramTypes[0] + "] failed. Reason: " + t); + throw new PropertySetterException("Conversion to type ["+paramTypes[0]+ + "] failed. Reason: "+t); } - if (arg == null) { throw new PropertySetterException( - "Conversion to type [" + paramTypes[0] + "] failed."); + "Conversion to type ["+paramTypes[0]+"] failed."); } - - getLogger().debug("Setting property [{}] to [{}].", name, arg); - + LogLog.debug("Setting property [" + name + "] to [" +arg+"]."); try { - setter.invoke(obj, new Object[] { arg }); - } catch (Exception ex) { + setter.invoke(obj, new Object[] { arg }); + } catch (IllegalAccessException ex) { + throw new PropertySetterException(ex); + } catch (InvocationTargetException ex) { + if (ex.getTargetException() instanceof InterruptedException + || ex.getTargetException() instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + throw new PropertySetterException(ex); + } catch (RuntimeException ex) { throw new PropertySetterException(ex); } } - - public int canContainComponent(String name) { - String cName = capitalizeFirstLetter(name); - - Method method = getMethod("add" + cName); - - if (method != null) { - getLogger().debug( - "Found add {} method in class {}", cName, objClass.getName()); - - return AS_COLLECTION; - } - - PropertyDescriptor propertyDescriptor = getPropertyDescriptor(name); - - if (propertyDescriptor != null) { - Method setter = propertyDescriptor.getWriteMethod(); - - if (setter != null) { - getLogger().debug( - "Found setter method for property [{}] in class {}", name, - objClass.getName()); - - return AS_PROPERTY; - } - } - - // we have failed - return NOT_FOUND; - } - - public Class getObjClass() { - return objClass; - } - - public void addComponent(String name, Object childComponent) { - Class ccc = childComponent.getClass(); - name = capitalizeFirstLetter(name); - - Method method = getMethod("add" + name); - - // first let us use the addXXX method - if (method != null) { - Class[] params = method.getParameterTypes(); - - if (params.length == 1) { - if (params[0].isAssignableFrom(childComponent.getClass())) { - try { - method.invoke(this.obj, new Object[] { childComponent }); - } catch (Exception e) { - getLogger().error( - "Could not invoke method " + method.getName() + " in class " - + obj.getClass().getName() + " with parameter of type " - + ccc.getName(), e); - } - } else { - getLogger().error( - "A \"" + ccc.getName() + "\" object is not assignable to a \"" - + params[0].getName() + "\" variable."); - getLogger().error( - "The class \"" + params[0].getName() + "\" was loaded by "); - getLogger().error( - "[" + params[0].getClassLoader() + "] whereas object of type "); - getLogger().error( - "\"" + ccc.getName() + "\" was loaded by [" + ccc.getClassLoader() - + "]."); - } - } - } else { - getLogger().error( - "Could not find method [" + "add" + name + "] in class [" - + objClass.getName() + "]."); - } - } - - public void setComponent(String name, Object childComponent) { - PropertyDescriptor propertyDescriptor = getPropertyDescriptor(name); - - if (propertyDescriptor == null) { - getLogger().warn( - "Could not find PropertyDescriptor for [" + name + "] in " - + objClass.getName()); - - return; - } - - Method setter = propertyDescriptor.getWriteMethod(); - - if (setter == null) { - getLogger().warn( - "Not setter method for property [" + name + "] in " - + obj.getClass().getName()); - - return; - } - - Class[] paramTypes = setter.getParameterTypes(); - - if (paramTypes.length != 1) { - getLogger().error( - "Wrong number of parameters in setter method for property [" + name - + "] in " + obj.getClass().getName()); - - return; - } - - try { - setter.invoke(obj, new Object[] { childComponent }); - getLogger().debug( - "Set child component of type [{}] for [{}].", objClass.getName(), - childComponent.getClass().getName()); - } catch (Exception e) { - getLogger().error( - "Could not set component " + obj + " for parent component " + obj, e); - } - } - - String capitalizeFirstLetter(String name) { - return name.substring(0, 1).toUpperCase() + name.substring(1); - } + /** Convert val a String parameter to an object of a given type. */ - protected Object convertArg(String val, Class type) { - if (val == null) { - return null; + protected + Object convertArg(String val, Class type) { + if(val == null) { + return null; } String v = val.trim(); - if (String.class.isAssignableFrom(type)) { return val; } else if (Integer.TYPE.isAssignableFrom(type)) { @@ -380,48 +283,33 @@ protected Object convertArg(String val, Class type) { return Boolean.FALSE; } } else if (Priority.class.isAssignableFrom(type)) { - return OptionConverter.toLevel(v, (Level) Level.DEBUG); - } - - return null; - } - - protected Method getMethod(String methodName) { - if (methodDescriptors == null) { - introspect(); + return OptionConverter.toLevel(v, Level.DEBUG); + } else if (ErrorHandler.class.isAssignableFrom(type)) { + return OptionConverter.instantiateByClassName(v, + ErrorHandler.class, null); } - - for (int i = 0; i < methodDescriptors.length; i++) { - if (methodName.equals(methodDescriptors[i].getName())) { - return methodDescriptors[i].getMethod(); - } - } - return null; } - - protected PropertyDescriptor getPropertyDescriptor(String name) { + + + protected + PropertyDescriptor getPropertyDescriptor(String name) { if (props == null) { - introspect(); + introspect(); } - + for (int i = 0; i < props.length; i++) { if (name.equals(props[i].getName())) { - return props[i]; + return props[i]; } } - return null; } - - /** - * @deprecated - */ - public - void activate() { - if (obj instanceof OptionHandler) { - ((OptionHandler) obj).activateOptions(); - } + + public + void activate() { + if (obj instanceof OptionHandler) { + ((OptionHandler) obj).activateOptions(); } - + } } diff --git a/src/main/java/org/apache/log4j/config/PropertySetterException.java b/src/main/java/org/apache/log4j/config/PropertySetterException.java index 9768f1f02b..c6314cca41 100644 --- a/src/main/java/org/apache/log4j/config/PropertySetterException.java +++ b/src/main/java/org/apache/log4j/config/PropertySetterException.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -24,6 +25,7 @@ * @since 1.1 */ public class PropertySetterException extends Exception { + private static final long serialVersionUID = -1352613734254235861L; protected Throwable rootCause; public diff --git a/src/main/java/org/apache/log4j/config/package.html b/src/main/java/org/apache/log4j/config/package.html index 9bd887941b..973dce4ffe 100644 --- a/src/main/java/org/apache/log4j/config/package.html +++ b/src/main/java/org/apache/log4j/config/package.html @@ -1,4 +1,21 @@ + Package used in getting/setting component properties. diff --git a/src/main/java/org/apache/log4j/db/ConnectionSource.java b/src/main/java/org/apache/log4j/db/ConnectionSource.java deleted file mode 100644 index 0578734bb9..0000000000 --- a/src/main/java/org/apache/log4j/db/ConnectionSource.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.db; - -import org.apache.log4j.spi.Component; -import org.apache.log4j.spi.OptionHandler; - -import java.sql.Connection; -import java.sql.SQLException; - - -/** - * The ConnectionSource interface provides a pluggable means of - * transparently obtaining JDBC {@link java.sql.Connection}s for log4j classes - * that require the use of a {@link java.sql.Connection}. - * - * @author Ray DeCampo - */ -public interface ConnectionSource extends Component, OptionHandler { - - final int UNKNOWN_DIALECT = 0; - final int POSTGRES_DIALECT = 1; - final int MYSQL_DIALECT = 2; - final int ORACLE_DIALECT = 3; - final int MSSQL_DIALECT = 4; - final int HSQL_DIALECT = 5; - /** - * Obtain a {@link java.sql.Connection} for use. The client is - * responsible for closing the {@link java.sql.Connection} when it is no - * longer required. - * - * @throws SQLException if a {@link java.sql.Connection} could not be - * obtained - */ - Connection getConnection() throws SQLException; - - /** - * Get the SQL dialect that should be used for this connection. Note that the - * dialect is not needed if the JDBC driver supports the getGeneratedKeys - * method. - */ - int getSQLDialectCode(); - - /** - * If the connection supports the JDBC 3.0 getGeneratedKeys method, then - * we do not need any specific dialect support. - */ - boolean supportsGetGeneratedKeys(); - - /** - * If the connection does not support batch updates, we will avoid using them. - */ - public boolean supportsBatchUpdates(); -} diff --git a/src/main/java/org/apache/log4j/db/ConnectionSourceSkeleton.java b/src/main/java/org/apache/log4j/db/ConnectionSourceSkeleton.java deleted file mode 100644 index fd4b014bf4..0000000000 --- a/src/main/java/org/apache/log4j/db/ConnectionSourceSkeleton.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.db; - -import org.apache.log4j.db.dialect.Util; -import org.apache.log4j.spi.ComponentBase; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.SQLException; - - -/** - * @author Ceki Gülcü - */ -public abstract class ConnectionSourceSkeleton extends ComponentBase implements ConnectionSource { - private String user = null; - private String password = null; - - // initially we have an unkonw dialect - private int dialectCode = UNKNOWN_DIALECT; - private boolean supportsGetGeneratedKeys = false; - private boolean supportsBatchUpdates = false; - - - /** - * Learn relevant information about this connection source. - * - */ - public void discoverConnnectionProperties() { - try { - Connection connection = getConnection(); - if (connection == null) { - getLogger().warn("Could not get a conneciton"); - return; - } - DatabaseMetaData meta = connection.getMetaData(); - Util util = new Util(); - util.setLoggerRepository(repository); - supportsGetGeneratedKeys = util.supportsGetGeneratedKeys(meta); - supportsBatchUpdates = util.supportsBatchUpdates(meta); - dialectCode = Util.discoverSQLDialect(meta); - } catch (SQLException se) { - getLogger().warn("Could not discover the dialect to use.", se); - } - } - - /** - * Does this connection support the JDBC Connection.getGeneratedKeys method? - */ - public final boolean supportsGetGeneratedKeys() { - return supportsGetGeneratedKeys; - } - - public final int getSQLDialectCode() { - return dialectCode; - } - - /** - * Get the password for this connection source. - */ - public final String getPassword() { - return password; - } - - /** - * Sets the password. - * @param password The password to set - */ - public final void setPassword(final String password) { - this.password = password; - } - - /** - * Get the user for this connection source. - */ - public final String getUser() { - return user; - } - - /** - * Sets the username. - * @param username The username to set - */ - public final void setUser(final String username) { - this.user = username; - } - - /** - * Does this connection support batch updates? - */ - public final boolean supportsBatchUpdates() { - return supportsBatchUpdates; - } -} diff --git a/src/main/java/org/apache/log4j/db/CustomSQLDBReceiver.java b/src/main/java/org/apache/log4j/db/CustomSQLDBReceiver.java deleted file mode 100644 index 7a186ca4a8..0000000000 --- a/src/main/java/org/apache/log4j/db/CustomSQLDBReceiver.java +++ /dev/null @@ -1,442 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.db; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Hashtable; -import java.util.StringTokenizer; - -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.apache.log4j.plugins.Pauseable; -import org.apache.log4j.plugins.Receiver; -import org.apache.log4j.scheduler.Job; -import org.apache.log4j.scheduler.Scheduler; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.LoggerRepositoryEx; -import org.apache.log4j.spi.ThrowableInformation; -import org.apache.log4j.spi.LocationInfo; - -/** - * Converts log data stored in a database into LoggingEvents. - *

    - * NOTE: This receiver cannot yet be created through Chainsaw's receiver panel. - * It must be created through an XML configuration file. - *

    - * This receiver supports database configuration via ConnectionSource, in the - * org.apache.log4j.db package: DriverManagerConnectionSource, - * DataSourceConnectionSource, JNDIConnectionSource - *

    - * This database receiver differs from DBReceiver in that this receiver relies - * on custom SQL to retrieve logging event data, where DBReceiver requires the - * use of a log4j-defined schema. - *

    - * A 'refreshMillis' int parameter controls SQL execution. If 'refreshMillis' is - * zero (the default), the receiver will run only one time. If it is set to any - * other numeric value, the SQL will be executed on a recurring basis every - * 'refreshMillis' milliseconds. - *

    - * The receiver closes the connection and acquires a new connection on each - * execution of the SQL (use pooled connections if possible). - *

    - * If the SQL will be executing on a recurring basis, specify the IDField param - - * the column name holding the unique identifier (int) representing the logging - * event. - *

    - * As events are retrieved, the column represented by IDField is examined and - * the largest value is held and used by the next execution of the SQL statement - * to avoid retrieving previously processed events. - *

    - * As an example, the IDField references a 'COUNTER' (int, auto-increment, - * unique) column. The first execution of the SQL statement returns 500 rows, - * with a final value in the COUNTER field of 500. - *

    - * The SQL statement is manipulated prior to the next execution, adding ' WHERE - * COUNTER > 500' to the statement to avoid retrieval of previously processed - * events. - *

    - * The select statement must provide ALL fields which define a LoggingEvent. - *

    - * The SQL statement MUST include the columns: LOGGER, TIMESTAMP, LEVEL, THREAD, - * MESSAGE, NDC, MDC, CLASS, METHOD, FILE, LINE, PROPERTIES, EXCEPTION - *

    - * Use ' AS ' in the SQL statement to alias the SQL's column names to match your - * database schema. (see example below). - *

    - * Include all fields in the SQL statement, even if you don't have data for the - * field (specify an empty string as the value for columns which you don't have - * data). - *

    - * The TIMESTAMP column must be a datetime. - *

    - * Both a PROPERTIES column and an MDC column are supported. These fields - * represent Maps on the logging event, but require the use of string - * concatenation database functions to hold the (possibly multiple) name/value - * pairs in the column. - *

    - * For example, to include both 'userid' and 'lastname' properties in the - * logging event (from either the PROPERTIES or MDC columns), the name/value - * pairs must be concatenated together by your database. - *

    - * The resulting PROPERTIES or MDC column must have data in this format: {{name, - * value, name2, value2}} - *

    - * The resulting PROPERTIES column would contain this text: {{userid, someone, - * lastname, mylastname}} - *

    - * Here is an example of concatenating a PROPERTIES or MDC column using MySQL's - * concat function, where the 'application' and 'hostname' parameters were fixed - * text, but the 'log4jid' key's value is the value of the COUNTER column: - *

    - * concat("{{application,databaselogs,hostname,mymachine,log4jid,", COUNTER, - * "}}") as PROPERTIES - *

    - * log4jid is a special property that is used by Chainsaw to represent an 'ID' - * field. Specify this property to ensure you can map events in Chainsaw to - * events in the database if you need to go back and view events at a later time - * or save the events to XML for later analysis. - *

    - * Here is a complete MySQL SQL statement which can be used to provide events to - * Chainsaw: - *

    - * select logger as LOGGER, timestamp as TIMESTAMP, level as LEVEL, thread as - * THREAD, message as MESSAGE, ndc as NDC, mdc as MDC, class as CLASS, method as - * METHOD, file as FILE, line as LINE, - * concat("{{application,databaselogs,hostname,mymachine, log4jid,", - * COUNTER,"}}") as PROPERTIES, "" as EXCEPTION from logtable - *

    - * @author Scott Deboy - *

    - */ -public class CustomSQLDBReceiver extends Receiver implements Pauseable { - - protected volatile Connection connection = null; - - protected String sqlStatement = ""; - - /** - * By default we refresh data every 1000 milliseconds. - * - * @see #setRefreshMillis - */ - static int DEFAULT_REFRESH_MILLIS = 1000; - - int refreshMillis = DEFAULT_REFRESH_MILLIS; - - protected String idField = null; - - int lastID = -1; - - private static final String WHERE_CLAUSE = " WHERE "; - - private static final String AND_CLAUSE = " AND "; - - private boolean whereExists = false; - - private boolean paused = false; - - private ConnectionSource connectionSource; - - public static final String LOG4J_ID_KEY = "log4jid"; - - private Job customReceiverJob; - - public void activateOptions() { - - if(connectionSource == null) { - throw new IllegalStateException( - "CustomSQLDBReceiver cannot function without a connection source"); - } - whereExists = (sqlStatement.toUpperCase().indexOf(WHERE_CLAUSE) > -1); - - customReceiverJob = new CustomReceiverJob(); - - if(this.repository == null) { - throw new IllegalStateException( - "CustomSQLDBReceiver cannot function without a reference to its owning repository"); - } - - - - if (repository instanceof LoggerRepositoryEx) { - Scheduler scheduler = ((LoggerRepositoryEx) repository).getScheduler(); - - scheduler.schedule( - customReceiverJob, System.currentTimeMillis() + 500, refreshMillis); - } - - } - - void closeConnection(Connection connection) { - if (connection != null) { - try { - // LogLog.warn("closing the connection. ", new Exception("x")); - connection.close(); - } catch (SQLException sqle) { - // nothing we can do here - } - } - } - - public void setRefreshMillis(int refreshMillis) { - this.refreshMillis = refreshMillis; - } - - public int getRefreshMillis() { - return refreshMillis; - } - - /** - * @return Returns the connectionSource. - */ - public ConnectionSource getConnectionSource() { - return connectionSource; - } - - /** - * @param connectionSource - * The connectionSource to set. - */ - public void setConnectionSource(ConnectionSource connectionSource) { - this.connectionSource = connectionSource; - } - - public void close() { - try { - if ((connection != null) && !connection.isClosed()) { - connection.close(); - } - } catch (SQLException e) { - e.printStackTrace(); - } finally { - connection = null; - } - } - - public void finalize() throws Throwable { - super.finalize(); - close(); - } - - /* - * (non-Javadoc) - * - * @see org.apache.log4j.plugins.Plugin#shutdown() - */ - public void shutdown() { - getLogger().info("removing receiverJob from the Scheduler."); - - if(this.repository instanceof LoggerRepositoryEx) { - Scheduler scheduler = ((LoggerRepositoryEx) repository).getScheduler(); - scheduler.delete(customReceiverJob); - } - - lastID = -1; - } - - public void setSql(String s) { - sqlStatement = s; - } - - public String getSql() { - return sqlStatement; - } - - public void setIDField(String id) { - idField = id; - } - - public String getIDField() { - return idField; - } - - public synchronized void setPaused(boolean p) { - paused = p; - } - - public synchronized boolean isPaused() { - return paused; - } - - class CustomReceiverJob implements Job { - public void execute() { - Connection connection = null; - - int oldLastID = lastID; - try { - connection = connectionSource.getConnection(); - Statement statement = connection.createStatement(); - - Logger eventLogger = null; - long timeStamp = 0L; - String level = null; - String threadName = null; - Object message = null; - String ndc = null; - Hashtable mdc = null; - String[] exception = null; - String className = null; - String methodName = null; - String fileName = null; - String lineNumber = null; - Hashtable properties = null; - - String currentSQLStatement = sqlStatement; - if (whereExists) { - currentSQLStatement = sqlStatement + AND_CLAUSE + idField - + " > " + lastID; - } else { - currentSQLStatement = sqlStatement + WHERE_CLAUSE + idField - + " > " + lastID; - } - - ResultSet rs = statement.executeQuery(currentSQLStatement); - - int i = 0; - while (rs.next()) { - // add a small break every 1000 received events - if (++i == 1000) { - synchronized (this) { - try { - // add a delay - wait(300); - } catch (InterruptedException ie) { - } - i = 0; - } - } - eventLogger = Logger.getLogger(rs.getString("LOGGER")); - timeStamp = rs.getTimestamp("TIMESTAMP").getTime(); - - level = rs.getString("LEVEL"); - threadName = rs.getString("THREAD"); - message = rs.getString("MESSAGE"); - ndc = rs.getString("NDC"); - - String mdcString = rs.getString("MDC"); - mdc = new Hashtable(); - - if (mdcString != null) { - // support MDC being wrapped in {{name, value}} - // or - // just name, value - if ((mdcString.indexOf("{{") > -1) - && (mdcString.indexOf("}}") > -1)) { - mdcString = mdcString - .substring(mdcString.indexOf("{{") + 2, - mdcString.indexOf("}}")); - } - - StringTokenizer tok = new StringTokenizer(mdcString, - ","); - - while (tok.countTokens() > 1) { - mdc.put(tok.nextToken(), tok.nextToken()); - } - } - - exception = new String[] { rs.getString("EXCEPTION") }; - className = rs.getString("CLASS"); - methodName = rs.getString("METHOD"); - fileName = rs.getString("FILE"); - lineNumber = rs.getString("LINE"); - - // if properties are provided in the - // SQL they can be used here (for example, to route - // events to a unique tab in - // Chainsaw if the machinename and/or appname - // property - // are set) - String propertiesString = rs.getString("PROPERTIES"); - properties = new Hashtable(); - - if (propertiesString != null) { - // support properties being wrapped in {{name, - // value}} or just name, value - if ((propertiesString.indexOf("{{") > -1) - && (propertiesString.indexOf("}}") > -1)) { - propertiesString = propertiesString.substring( - propertiesString.indexOf("{{") + 2, - propertiesString.indexOf("}}")); - } - - StringTokenizer tok2 = new StringTokenizer( - propertiesString, ","); - while (tok2.countTokens() > 1) { - String name = tok2.nextToken(); - String value = tok2.nextToken(); - if (name.equals(LOG4J_ID_KEY)) { - try { - int thisInt = Integer.parseInt(value); - value = String.valueOf(thisInt); - if (thisInt > lastID) { - lastID = thisInt; - } - } catch (Exception e) { - } - } - properties.put(name, value); - } - } - - Level levelImpl = Level.toLevel(level); - LoggingEvent event = new LoggingEvent( - eventLogger.getName(), eventLogger, levelImpl, - message, null); - event.setLocationInformation(new LocationInfo(fileName, - className, methodName, lineNumber)); - properties.putAll(mdc); - event.setTimeStamp(timeStamp); - event.setThrowableInformation(new ThrowableInformation( - exception)); - - event.setProperties(properties); - event.setThreadName(threadName); - event.setNDC(ndc); - doPost(event); - } - //log when rows are retrieved - if (lastID != oldLastID) { - getLogger().debug("lastID: " + lastID); - oldLastID = lastID; - } - - statement.close(); - statement = null; - } catch (SQLException sqle) { - getLogger() - .error("*************Problem receiving events", sqle); - } finally { - closeConnection(connection); - } - - // if paused, loop prior to executing sql query - synchronized (this) { - while (isPaused()) { - try { - wait(1000); - } catch (InterruptedException ie) { - } - } - } - } - } -} diff --git a/src/main/java/org/apache/log4j/db/DBAppender.java b/src/main/java/org/apache/log4j/db/DBAppender.java deleted file mode 100644 index 215e799c3f..0000000000 --- a/src/main/java/org/apache/log4j/db/DBAppender.java +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.db; - -import org.apache.log4j.AppenderSkeleton; -import org.apache.log4j.db.dialect.SQLDialect; -import org.apache.log4j.db.dialect.Util; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.LocationInfo; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import java.util.Iterator; -import java.util.Set; -import java.lang.reflect.*; - - -/** - * The DBAppender inserts loggin events into three database tables in a format - * independent of the Java programming language. The three tables that - * DBAppender inserts to must exists before DBAppender can be used. These tables - * may be created with the help of SQL scripts found in the - * src/java/org/apache/log4j/db/dialect directory. There is a - * specific script for each of the most popular database systems. If the script - * for your particular type of database system is missing, it should be quite - * easy to write one, taking example on the already existing scripts. If you - * send them to us, we will gladly include missing scripts in future releases. - * - *

    - * If the JDBC driver you are using supports the - * {@link java.sql.Statement#getGeneratedKeys}method introduced in JDBC 3.0 - * specification, then you are all set. Otherwise, there must be an - * {@link SQLDialect}appropriate for your database system. Currently, we have - * dialects for PostgreSQL, MySQL, Oracle and MsSQL. As mentioed previously, an - * SQLDialect is required only if the JDBC driver for your database system does - * not support the {@link java.sql.Statement#getGeneratedKeys getGeneratedKeys} - * method. - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    RDBMSsupports
    getGeneratedKeys() method
    specific
    SQLDialect support
    PostgreSQLNOpresent and used
    MySQLYESpresent, but not actually needed or used
    OracleYESpresent, but not actually needed or used
    DB2YESnot present, and not needed or used
    MsSQLYESnot present, and not needed or used
    HSQLNOpresent and used
    - *

    - * Performance: Experiments show that writing a single event into the - * database takes approximately 50 milliseconds, on a "standard" PC. If pooled - * connections are used, this figure drops to under 10 milliseconds. Note that - * most JDBC drivers already ship with connection pooling support. - *

    - * - * - * - *

    - * Configuration DBAppender can be configured programmatically, or using - * {@link org.apache.log4j.joran.JoranConfigurator JoranConfigurator}. Example - * scripts can be found in the tests/input/db directory. - * - * @author Ceki Gülcü - * @author Ray DeCampo - * @since 1.3 - */ -public class DBAppender extends AppenderSkeleton { - static final String insertPropertiesSQL = - "INSERT INTO logging_event_property (event_id, mapped_key, mapped_value) VALUES (?, ?, ?)"; - static final String insertExceptionSQL = - "INSERT INTO logging_event_exception (event_id, i, trace_line) VALUES (?, ?, ?)"; - static final String insertSQL; - private static final Method GET_GENERATED_KEYS_METHOD; - - - static { - StringBuffer sql = new StringBuffer(); - sql.append("INSERT INTO logging_event ("); - sql.append("sequence_number, "); - sql.append("timestamp, "); - sql.append("rendered_message, "); - sql.append("logger_name, "); - sql.append("level_string, "); - sql.append("ndc, "); - sql.append("thread_name, "); - sql.append("reference_flag, "); - sql.append("caller_filename, "); - sql.append("caller_class, "); - sql.append("caller_method, "); - sql.append("caller_line) "); - sql.append(" VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?, ?, ?, ?)"); - insertSQL = sql.toString(); - // - // PreparedStatement.getGeneratedKeys added in JDK 1.4 - // - Method getGeneratedKeysMethod; - try { - getGeneratedKeysMethod = PreparedStatement.class.getMethod("getGeneratedKeys", null); - } catch(Exception ex) { - getGeneratedKeysMethod = null; - } - GET_GENERATED_KEYS_METHOD = getGeneratedKeysMethod; - } - - ConnectionSource connectionSource; - boolean cnxSupportsGetGeneratedKeys = false; - boolean cnxSupportsBatchUpdates = false; - SQLDialect sqlDialect; - boolean locationInfo = false; - - - public DBAppender() { - super(false); - } - - public void activateOptions() { - getLogger().debug("DBAppender.activateOptions called"); - - if (connectionSource == null) { - throw new IllegalStateException( - "DBAppender cannot function without a connection source"); - } - - sqlDialect = Util.getDialectFromCode(connectionSource.getSQLDialectCode()); - if (GET_GENERATED_KEYS_METHOD != null) { - cnxSupportsGetGeneratedKeys = connectionSource.supportsGetGeneratedKeys(); - } else { - cnxSupportsGetGeneratedKeys = false; - } - cnxSupportsBatchUpdates = connectionSource.supportsBatchUpdates(); - if (!cnxSupportsGetGeneratedKeys && (sqlDialect == null)) { - throw new IllegalStateException( - "DBAppender cannot function if the JDBC driver does not support getGeneratedKeys method *and* without a specific SQL dialect"); - } - - // all nice and dandy on the eastern front - super.activateOptions(); - } - - /** - * @return Returns the connectionSource. - */ - public ConnectionSource getConnectionSource() { - return connectionSource; - } - - /** - * @param connectionSource - * The connectionSource to set. - */ - public void setConnectionSource(ConnectionSource connectionSource) { - getLogger().debug("setConnectionSource called for DBAppender"); - this.connectionSource = connectionSource; - } - - protected void append(LoggingEvent event) { - Connection connection = null; - try { - connection = connectionSource.getConnection(); - connection.setAutoCommit(false); - - PreparedStatement insertStatement = - connection.prepareStatement(insertSQL); - insertStatement.setLong(1, event.getSequenceNumber()); - insertStatement.setLong(2, event.getTimeStamp()); - insertStatement.setString(3, event.getRenderedMessage()); - insertStatement.setString(4, event.getLoggerName()); - insertStatement.setString(5, event.getLevel().toString()); - insertStatement.setString(6, event.getNDC()); - insertStatement.setString(7, event.getThreadName()); - insertStatement.setShort(8, DBHelper.computeReferenceMask(event)); - - LocationInfo li; - - if (event.locationInformationExists() || locationInfo) { - li = event.getLocationInformation(); - } else { - li = LocationInfo.NA_LOCATION_INFO; - } - - insertStatement.setString(9, li.getFileName()); - insertStatement.setString(10, li.getClassName()); - insertStatement.setString(11, li.getMethodName()); - insertStatement.setString(12, li.getLineNumber()); - - int updateCount = insertStatement.executeUpdate(); - if (updateCount != 1) { - getLogger().warn("Failed to insert loggingEvent"); - } - - ResultSet rs = null; - Statement idStatement = null; - boolean gotGeneratedKeys = false; - if (cnxSupportsGetGeneratedKeys) { - try { - rs = (ResultSet) GET_GENERATED_KEYS_METHOD.invoke(insertStatement, null); - gotGeneratedKeys = true; - } catch(InvocationTargetException ex) { - Throwable target = ex.getTargetException(); - if (target instanceof SQLException) { - throw (SQLException) target; - } - throw ex; - } catch(IllegalAccessException ex) { - getLogger().warn("IllegalAccessException invoking PreparedStatement.getGeneratedKeys", ex); - } - } - - if (!gotGeneratedKeys) { - insertStatement.close(); - insertStatement = null; - - idStatement = connection.createStatement(); - idStatement.setMaxRows(1); - rs = idStatement.executeQuery(sqlDialect.getSelectInsertId()); - } - - // A ResultSet cursor is initially positioned before the first row; the - // first call to the method next makes the first row the current row - rs.next(); - int eventId = rs.getInt(1); - - rs.close(); - - // we no longer need the insertStatement - if(insertStatement != null) { - insertStatement.close(); - insertStatement = null; - } - - if(idStatement != null) { - idStatement.close(); - idStatement = null; - } - - Set propertiesKeys = event.getPropertyKeySet(); - - if (propertiesKeys.size() > 0) { - PreparedStatement insertPropertiesStatement = - connection.prepareStatement(insertPropertiesSQL); - - for (Iterator i = propertiesKeys.iterator(); i.hasNext();) { - String key = (String) i.next(); - String value = (String) event.getProperty(key); - - //LogLog.info("id " + eventId + ", key " + key + ", value " + value); - insertPropertiesStatement.setInt(1, eventId); - insertPropertiesStatement.setString(2, key); - insertPropertiesStatement.setString(3, value); - - if (cnxSupportsBatchUpdates) { - insertPropertiesStatement.addBatch(); - } else { - insertPropertiesStatement.execute(); - } - } - - if (cnxSupportsBatchUpdates) { - insertPropertiesStatement.executeBatch(); - } - - insertPropertiesStatement.close(); - insertPropertiesStatement = null; - } - - String[] strRep = event.getThrowableStrRep(); - - if (strRep != null) { - getLogger().debug("Logging an exception"); - - PreparedStatement insertExceptionStatement = - connection.prepareStatement(insertExceptionSQL); - - for (short i = 0; i < strRep.length; i++) { - insertExceptionStatement.setInt(1, eventId); - insertExceptionStatement.setShort(2, i); - insertExceptionStatement.setString(3, strRep[i]); - if (cnxSupportsBatchUpdates) { - insertExceptionStatement.addBatch(); - } else { - insertExceptionStatement.execute(); - } - } - if (cnxSupportsBatchUpdates) { - insertExceptionStatement.executeBatch(); - } - insertExceptionStatement.close(); - insertExceptionStatement = null; - } - - connection.commit(); - } catch (Throwable sqle) { - getLogger().error("problem appending event", sqle); - } finally { - DBHelper.closeConnection(connection); - } - } - - public void close() { - closed = true; - } - - /** - * Returns value of the LocationInfo property which determines whether - * caller's location info is written to the database. - */ - public boolean getLocationInfo() { - return locationInfo; - } - - /** - * If true, the information written to the database will include caller's - * location information. Due to performance concerns, by default no location - * information is written to the database. - */ - public void setLocationInfo(boolean locationInfo) { - this.locationInfo = locationInfo; - } - - /** - * Gets whether appender requires a layout. - * @return false - */ - public boolean requiresLayout() { - return false; - } - -} diff --git a/src/main/java/org/apache/log4j/db/DBHelper.java b/src/main/java/org/apache/log4j/db/DBHelper.java deleted file mode 100644 index b4005068b0..0000000000 --- a/src/main/java/org/apache/log4j/db/DBHelper.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.db; - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Set; - -import org.apache.log4j.spi.LoggingEvent; - -/** - * @author Ceki Gülcü - * - */ -public class DBHelper { - - public final static short PROPERTIES_EXIST = 0x01; - public final static short EXCEPTION_EXISTS = 0x02; - - public static short computeReferenceMask(LoggingEvent event) { - short mask = 0; - Set propertiesKeys = event.getPropertyKeySet(); - if(propertiesKeys.size() > 0) { - mask = PROPERTIES_EXIST; - } - String[] strRep = event.getThrowableStrRep(); - if(strRep != null) { - mask |= EXCEPTION_EXISTS; - } - return mask; - } - - static public void closeConnection(Connection connection) { - if(connection != null) { - try { - connection.close(); - } catch(SQLException sqle) { - // static utility classes should not log without an explicit repository - // reference - } - } - } - - public static void closeStatement(Statement statement) { - if(statement != null) { - try { - statement.close(); - } catch(SQLException sqle) { - } - } - } -} diff --git a/src/main/java/org/apache/log4j/db/DBReceiver.java b/src/main/java/org/apache/log4j/db/DBReceiver.java deleted file mode 100644 index 69effde438..0000000000 --- a/src/main/java/org/apache/log4j/db/DBReceiver.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.db; - -import org.apache.log4j.plugins.Pauseable; -import org.apache.log4j.plugins.Receiver; -import org.apache.log4j.scheduler.Scheduler; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggerRepositoryEx; - -/** - * - * @author Scott Deboy - * @author Ceki Gülcü - * - */ -public class DBReceiver extends Receiver implements Pauseable { - /** - * By default we refresh data every 1000 milliseconds. - * @see #setRefreshMillis - */ - static int DEFAULT_REFRESH_MILLIS = 1000; - ConnectionSource connectionSource; - int refreshMillis = DEFAULT_REFRESH_MILLIS; - DBReceiverJob receiverJob; - boolean paused = false; - - public void activateOptions() { - - if(connectionSource == null) { - throw new IllegalStateException( - "DBAppender cannot function without a connection source"); - } - - receiverJob = new DBReceiverJob(this); - receiverJob.setLoggerRepository(repository); - - if(this.repository == null) { - throw new IllegalStateException( - "DBAppender cannot function without a reference to its owning repository"); - } - - if (repository instanceof LoggerRepositoryEx) { - Scheduler scheduler = ((LoggerRepositoryEx) repository).getScheduler(); - - scheduler.schedule( - receiverJob, System.currentTimeMillis() + 500, refreshMillis); - } - - } - - public void setRefreshMillis(int refreshMillis) { - this.refreshMillis = refreshMillis; - } - - public int getRefreshMillis() { - return refreshMillis; - } - - - /** - * @return Returns the connectionSource. - */ - public ConnectionSource getConnectionSource() { - return connectionSource; - } - - - /** - * @param connectionSource The connectionSource to set. - */ - public void setConnectionSource(ConnectionSource connectionSource) { - this.connectionSource = connectionSource; - } - - - /* (non-Javadoc) - * @see org.apache.log4j.plugins.Plugin#shutdown() - */ - public void shutdown() { - getLogger().info("removing receiverJob from the Scheduler."); - - if(this.repository instanceof LoggerRepositoryEx) { - Scheduler scheduler = ((LoggerRepositoryEx) repository).getScheduler(); - scheduler.delete(receiverJob); - } - } - - - /* (non-Javadoc) - * @see org.apache.log4j.plugins.Pauseable#setPaused(boolean) - */ - public void setPaused(boolean paused) { - this.paused = paused; - } - - /* (non-Javadoc) - * @see org.apache.log4j.plugins.Pauseable#isPaused() - */ - public boolean isPaused() { - return paused; - } -} diff --git a/src/main/java/org/apache/log4j/db/DBReceiverJob.java b/src/main/java/org/apache/log4j/db/DBReceiverJob.java deleted file mode 100644 index 5240404973..0000000000 --- a/src/main/java/org/apache/log4j/db/DBReceiverJob.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.db; - -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.apache.log4j.helpers.Constants; -import org.apache.log4j.scheduler.Job; -import org.apache.log4j.spi.ComponentBase; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.ThrowableInformation; -import org.apache.log4j.spi.LocationInfo; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Vector; - -/** - * Actual retrieval of data is made by the instance of DBReceiverJob associated - * with DBReceiver. - * - * @author Ceki Gülcü - */ -class DBReceiverJob extends ComponentBase implements Job { - - String sqlException = "SELECT trace_line FROM logging_event_exception where event_id=? ORDER by i ASC"; - String sqlProperties = "SELECT mapped_key, mapped_value FROM logging_event_property WHERE event_id=?"; - String sqlSelect = - "SELECT " + - "sequence_number, timestamp, rendered_message, logger_name, " + - "level_string, ndc, thread_name, reference_flag, " + - "caller_filename, caller_class, caller_method, caller_line, " + - "event_id " + - "FROM logging_event " + - "WHERE event_id > ? ORDER BY event_id ASC"; - - - long lastId = 0; - - DBReceiver parentDBReceiver; - - DBReceiverJob(DBReceiver parent) { - parentDBReceiver = parent; - } - - public void execute() { - getLogger().debug("DBReceiverJob.execute() called"); - - Connection connection = null; - - try { - connection = parentDBReceiver.connectionSource.getConnection(); - PreparedStatement statement = connection.prepareStatement(sqlSelect); - statement.setLong(1, lastId); - ResultSet rs = statement.executeQuery(); - //rs.beforeFirst(); - - while (rs.next()) { - LoggingEvent event = new LoggingEvent(); - - event.setSequenceNumber(rs.getLong(1)); - event.setTimeStamp(rs.getLong(2)); - event.setRenderedMessage(rs.getString(3)); - event.setLoggerName(rs.getString(4)); - String levelStr = rs.getString(5); - - // TODO CG The conversion of levelStr should be more general - Level level = Level.toLevel(levelStr); - event.setLevel(level); - event.setNDC(rs.getString(6)); - event.setThreadName(rs.getString(7)); - - short mask = rs.getShort(8); - - String fileName = rs.getString(9); - String className = rs.getString(10); - String methodName = rs.getString(11); - String lineNumber = rs.getString(12).trim(); - - if (fileName.equals(LocationInfo.NA)) { - event.setLocationInformation(LocationInfo.NA_LOCATION_INFO); - } else { - event.setLocationInformation(new LocationInfo(fileName, className, - methodName, lineNumber)); - } - - long id = rs.getLong(13); - //LogLog.info("Received event with id=" + id); - lastId = id; - - // Scott asked for this info to be - event.setProperty(Constants.LOG4J_ID_KEY, Long.toString(id)); - - if ((mask & DBHelper.PROPERTIES_EXIST) != 0) { - getProperties(connection, id, event); - } - - if ((mask & DBHelper.EXCEPTION_EXISTS) != 0) { - getException(connection, id, event); - } - - if (!parentDBReceiver.isPaused()) { - parentDBReceiver.doPost(event); - } - } // while - statement.close(); - statement = null; - } catch (SQLException sqle) { - getLogger().error("Problem receiving events", sqle); - } finally { - closeConnection(connection); - } - } - - void closeConnection(Connection connection) { - if (connection != null) { - try { - //LogLog.warn("closing the connection. ", new Exception("x")); - connection.close(); - } catch (SQLException sqle) { - // nothing we can do here - } - } - } - - /** - * Retrieve the event properties from the logging_event_property table. - * - * @param connection - * @param id - * @param event - * @throws SQLException - */ - void getProperties(Connection connection, long id, LoggingEvent event) - throws SQLException { - - PreparedStatement statement = connection.prepareStatement(sqlProperties); - try { - statement.setLong(1, id); - ResultSet rs = statement.executeQuery(); - - while (rs.next()) { - String key = rs.getString(1); - String value = rs.getString(2); - event.setProperty(key, value); - } - } finally { - statement.close(); - } - } - - /** - * Retrieve the exception string representation from the - * logging_event_exception table. - * - * @param connection - * @param id - * @param event - * @throws SQLException - */ - void getException(Connection connection, long id, LoggingEvent event) - throws SQLException { - - PreparedStatement statement = null; - - try { - statement = connection.prepareStatement(sqlException); - statement.setLong(1, id); - ResultSet rs = statement.executeQuery(); - - Vector v = new Vector(); - - while (rs.next()) { - //int i = rs.getShort(1); - v.add(rs.getString(1)); - } - - int len = v.size(); - String[] strRep = new String[len]; - for (int i = 0; i < len; i++) { - strRep[i] = (String) v.get(i); - } - // we've filled strRep, we now attach it to the event - event.setThrowableInformation(new ThrowableInformation(strRep)); - } finally { - if (statement != null) { - statement.close(); - } - } - } -} \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/db/DataSourceConnectionSource.java b/src/main/java/org/apache/log4j/db/DataSourceConnectionSource.java deleted file mode 100644 index 1994bd028c..0000000000 --- a/src/main/java/org/apache/log4j/db/DataSourceConnectionSource.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.db; - - -import java.sql.Connection; -import java.sql.SQLException; - -import javax.sql.DataSource; - - -/** - * The DataSourceConnectionSource is an implementation of {@link ConnectionSource} - * that obtains the Connection in the recommended JDBC manner based on - * a {@link javax.sql.DataSource DataSource}. - *

    - * - * @author Ray DeCampo - * @author Ceki Gülcü - */ -public class DataSourceConnectionSource extends ConnectionSourceSkeleton { - - private DataSource dataSource; - - - public void activateOptions() { - //LogLog.debug("**********DataSourceConnectionSource.activateOptions called"); - if (dataSource == null) { - getLogger().warn("WARNING: No data source specified"); - } else { - Connection connection = null; - try { - connection = getConnection(); - } catch(SQLException se) { - getLogger().warn("Could not get a connection to discover the dialect to use.", se); - } - if(connection != null) { - discoverConnnectionProperties(); - } - if(!supportsGetGeneratedKeys() && getSQLDialectCode() == ConnectionSource.UNKNOWN_DIALECT) { - getLogger().warn("Connection does not support GetGeneratedKey method and could not discover the dialect."); - } - } - } - - /** - * @see org.apache.log4j.db.ConnectionSource#getConnection() - */ - public Connection getConnection() throws SQLException { - if (dataSource == null) { - getLogger().error("WARNING: No data source specified"); - return null; - } - - if (getUser() == null) { - return dataSource.getConnection(); - } else { - return dataSource.getConnection(getUser(), getPassword()); - } - } - - public DataSource getDataSource() { - return dataSource; - } - - public void setDataSource(DataSource dataSource) { - this.dataSource = dataSource; - } - - -} diff --git a/src/main/java/org/apache/log4j/db/DriverManagerConnectionSource.java b/src/main/java/org/apache/log4j/db/DriverManagerConnectionSource.java deleted file mode 100644 index 9bfdf65ef2..0000000000 --- a/src/main/java/org/apache/log4j/db/DriverManagerConnectionSource.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.db; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; - - -/** - * The DriverManagerConnectionSource is an implementation of {@link ConnectionSource} - * that obtains the Connection in the traditional JDBC manner based on the - * connection URL. - *

    - * Note that this class will establish a new Connection for each call to - * {@link #getConnection()}. It is recommended that you either use a JDBC - * driver that natively supported Connection pooling or that you create - * your own implementation of {@link ConnectionSource} that taps into whatever - * pooling mechanism you are already using. (If you have access to a JNDI - * implementation that supports {@link javax.sql.DataSource}s, e.g. within - * a J2EE application server, see {@link JNDIConnectionSource}). See - * below for a configuration example that uses the - * commons-dbcp - * package from Apache. - *

    - * Sample configuration:
    - *

    - *     <connectionSource class="org.apache.log4j.jdbc.DriverManagerConnectionSource">
    - *        <param name="driver" value="com.mysql.jdbc.Driver" />
    - *        <param name="url" value="jdbc:mysql://localhost:3306/mydb" />
    - *        <param name="username" value="myUser" />
    - *        <param name="password" value="myPassword" />
    - *     </connectionSource>
    - *  
    - *

    - * If you do not have another connection pooling mechanism - * built into your application, you can use the - * commons-dbcp - * package from Apache:
    - *

    - *     <connectionSource class="org.apache.log4j.jdbc.DriverManagerConnectionSource">
    - *        <param name="driver" value="org.apache.commons.dbcp.PoolingDriver" />
    - *        <param name="url" value="jdbc:apache:commons:dbcp:/myPoolingDriver" />
    - *     </connectionSource>
    - *  
    - * Then the configuration information for the commons-dbcp package goes into - * the file myPoolingDriver.jocl and is placed in the classpath. See the - * commons-dbcp - * documentation for details. - * - * @author Ray DeCampo - */ -public class DriverManagerConnectionSource extends ConnectionSourceSkeleton { - private String driverClass = null; - private String url = null; - - public void activateOptions() { - try { - if (driverClass != null) { - Class.forName(driverClass); - discoverConnnectionProperties(); - } else { - getLogger().error( - "WARNING: No JDBC driver specified for log4j DriverManagerConnectionSource."); - } - } catch (final ClassNotFoundException cnfe) { - getLogger().error("Could not load JDBC driver class: " + driverClass, cnfe); - } - } - - - /** - * @see org.apache.log4j.db.ConnectionSource#getConnection() - */ - public Connection getConnection() throws SQLException { - if (getUser() == null) { - return DriverManager.getConnection(url); - } else { - return DriverManager.getConnection(url, getUser(), getPassword()); - } - } - - - /** - * Returns the url. - * @return String - */ - public String getUrl() { - return url; - } - - - /** - * Sets the url. - * @param url The url to set - */ - public void setUrl(String url) { - this.url = url; - } - - - /** - * Returns the name of the driver class. - * @return String - */ - public String getDriverClass() { - return driverClass; - } - - - /** - * Sets the driver class. - * @param driverClass The driver class to set - */ - public void setDriverClass(String driverClass) { - this.driverClass = driverClass; - } -} diff --git a/src/main/java/org/apache/log4j/db/JNDIConnectionSource.java b/src/main/java/org/apache/log4j/db/JNDIConnectionSource.java deleted file mode 100644 index 707373820a..0000000000 --- a/src/main/java/org/apache/log4j/db/JNDIConnectionSource.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.db; - -import java.sql.Connection; -import java.sql.SQLException; - -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; - -// PortableRemoteObject was introduced in JDK 1.3. We won't use it. -// import javax.rmi.PortableRemoteObject; -import javax.sql.DataSource; - - -/** - * The JNDIConnectionSource is an implementation of - * {@link ConnectionSource} that obtains a {@link javax.sql.DataSource} from a - * JNDI provider and uses it to obtain a {@link java.sql.Connection}. It is - * primarily designed to be used inside of J2EE application servers or - * application server clients, assuming the application server supports remote - * access of {@link javax.sql.DataSource}s. In this way one can take - * advantage of connection pooling and whatever other goodies the application - * server provides. - *

    - * Sample configuration:
    - *

    - *    <connectionSource class="org.apache.log4j.jdbc.JNDIConnectionSource">
    - *        <param name="jndiLocation" value="jdbc/MySQLDS" />
    - *    </connectionSource>
    - *  
    - *

    - * Sample configuration (with username and password):
    - *

    - *    <connectionSource class="org.apache.log4j.jdbc.JNDIConnectionSource">
    - *        <param name="jndiLocation" value="jdbc/MySQLDS" />
    - *        <param name="username" value="myUser" />
    - *        <param name="password" value="myPassword" />
    - *    </connectionSource>
    - *  
    - *

    - * Note that this class will obtain an {@link javax.naming.InitialContext} - * using the no-argument constructor. This will usually work when executing - * within a J2EE environment. When outside the J2EE environment, make sure - * that you provide a jndi.properties file as described by your JNDI - * provider's documentation. - * - * @author Ray DeCampo - */ -public class JNDIConnectionSource - extends ConnectionSourceSkeleton { - private String jndiLocation = null; - private DataSource dataSource = null; - - /** - * @see org.apache.log4j.spi.OptionHandler#activateOptions() - */ - public void activateOptions() { - if (jndiLocation == null) { - getLogger().error("No JNDI location specified for JNDIConnectionSource."); - } - - discoverConnnectionProperties(); - - } - - /** - * @see org.apache.log4j.db.ConnectionSource#getConnection() - */ - public Connection getConnection() - throws SQLException { - Connection conn = null; - try { - - if(dataSource == null) { - dataSource = lookupDataSource(); - } - if (getUser() == null) { - conn = dataSource.getConnection(); - } else { - conn = dataSource.getConnection(getUser(), getPassword()); - } - } catch (final NamingException ne) { - getLogger().error("Error while getting data source", ne); - throw new SQLException("NamingException while looking up DataSource: " + ne.getMessage()); - } catch (final ClassCastException cce) { - getLogger().error("ClassCastException while looking up DataSource.", cce); - throw new SQLException("ClassCastException while looking up DataSource: " + cce.getMessage()); - } - - return conn; - } - - /** - * Returns the jndiLocation. - * @return String - */ - public String getJndiLocation() { - return jndiLocation; - } - - - /** - * Sets the jndiLocation. - * @param jndiLocation The jndiLocation to set - */ - public void setJndiLocation(String jndiLocation) { - this.jndiLocation = jndiLocation; - } - - - private DataSource lookupDataSource() - throws NamingException, SQLException { - DataSource ds; - Context ctx = new InitialContext(); - Object obj = ctx.lookup(jndiLocation); - - // PortableRemoteObject was introduced in JDK 1.3. We won't use it. - //ds = (DataSource)PortableRemoteObject.narrow(obj, DataSource.class); - ds = (DataSource) obj; - - if (ds == null) { - throw new SQLException("Failed to obtain data source from JNDI location " + jndiLocation); - } else { - return ds; - } - } -} diff --git a/src/main/java/org/apache/log4j/db/dialect/HSQLDBDialect.java b/src/main/java/org/apache/log4j/db/dialect/HSQLDBDialect.java deleted file mode 100644 index b558cd315a..0000000000 --- a/src/main/java/org/apache/log4j/db/dialect/HSQLDBDialect.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.db.dialect; - -/** - * The HSQLDB dialect. - * - * @author Ceki Gülcü -*/ -public class HSQLDBDialect implements SQLDialect { - public static final String SELECT_CURRVAL = "CALL IDENTITY()"; - - public String getSelectInsertId() { - return SELECT_CURRVAL; - } -} diff --git a/src/main/java/org/apache/log4j/db/dialect/MsSQLDialect.java b/src/main/java/org/apache/log4j/db/dialect/MsSQLDialect.java deleted file mode 100644 index 9b94e72db3..0000000000 --- a/src/main/java/org/apache/log4j/db/dialect/MsSQLDialect.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.db.dialect; - -/** -* The MS SQL Server dialect is untested. -* -* Note that the dialect is not needed if your JDBC driver supports -* the getGeneratedKeys method introduced in JDBC 3.0 specification. -* -* @author James Stauffer -*/ -public class MsSQLDialect implements SQLDialect { - public static final String SELECT_CURRVAL = "SELECT @@identity id"; - - public String getSelectInsertId() { - return SELECT_CURRVAL; - } -} diff --git a/src/main/java/org/apache/log4j/db/dialect/MySQLDialect.java b/src/main/java/org/apache/log4j/db/dialect/MySQLDialect.java deleted file mode 100644 index f61db1926a..0000000000 --- a/src/main/java/org/apache/log4j/db/dialect/MySQLDialect.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.db.dialect; - -/** - * - * - * @author Ceki - * - */ -public class MySQLDialect implements SQLDialect { - public static final String SELECT_LAST_INSERT_ID = "SELECT LAST_INSERT_ID()"; - - public String getSelectInsertId() { - return SELECT_LAST_INSERT_ID; - } -} diff --git a/src/main/java/org/apache/log4j/db/dialect/OracleDialect.java b/src/main/java/org/apache/log4j/db/dialect/OracleDialect.java deleted file mode 100644 index c0404136c6..0000000000 --- a/src/main/java/org/apache/log4j/db/dialect/OracleDialect.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.db.dialect; - -/** - * The Oracle dialect. Tested successfully on Oracle9i Release 9.2.0.3.0 by - * James Stauffer. - * - * @author Ceki Gülcü - */ -public class OracleDialect implements SQLDialect { - public static final String SELECT_CURRVAL = "SELECT logging_event_id_seq.currval from dual"; - - public String getSelectInsertId() { - return SELECT_CURRVAL; - } - -} diff --git a/src/main/java/org/apache/log4j/db/dialect/PostgreSQLDialect.java b/src/main/java/org/apache/log4j/db/dialect/PostgreSQLDialect.java deleted file mode 100644 index 0eff123eda..0000000000 --- a/src/main/java/org/apache/log4j/db/dialect/PostgreSQLDialect.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.db.dialect; - - -/** - * - * @author ceki - * - * To change the template for this generated type comment go to - * Window>Preferences>Java>Code Generation>Code and Comments - */ -public class PostgreSQLDialect - implements SQLDialect { - public static final String SELECT_CURRVAL = "SELECT currval('logging_event_id_seq')"; - - public String getSelectInsertId() { - return SELECT_CURRVAL; - } -} diff --git a/src/main/java/org/apache/log4j/db/dialect/SQLDialect.java b/src/main/java/org/apache/log4j/db/dialect/SQLDialect.java deleted file mode 100644 index b24e5aa00c..0000000000 --- a/src/main/java/org/apache/log4j/db/dialect/SQLDialect.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.db.dialect; - -/** - * @author ceki - * - */ -public interface SQLDialect { - - public String getSelectInsertId(); - -} diff --git a/src/main/java/org/apache/log4j/db/dialect/Util.java b/src/main/java/org/apache/log4j/db/dialect/Util.java deleted file mode 100644 index 05f5ba301d..0000000000 --- a/src/main/java/org/apache/log4j/db/dialect/Util.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.db.dialect; - -import org.apache.log4j.db.ConnectionSource; -import org.apache.log4j.spi.ComponentBase; - -import java.sql.DatabaseMetaData; -import java.sql.SQLException; - - -/** - * - * @author Ceki Gulcu - * - */ -public class Util extends ComponentBase { - private static final String POSTGRES_PART = "postgresql"; - private static final String MYSQL_PART = "mysql"; - private static final String ORACLE_PART = "oracle"; - //private static final String MSSQL_PART = "mssqlserver4"; - private static final String MSSQL_PART = "microsoft"; - private static final String HSQL_PART = "hsql"; - - public static int discoverSQLDialect(DatabaseMetaData meta) { - int dialectCode = 0; - - try { - - String dbName = meta.getDatabaseProductName().toLowerCase(); - - if (dbName.indexOf(POSTGRES_PART) != -1) { - return ConnectionSource.POSTGRES_DIALECT; - } else if (dbName.indexOf(MYSQL_PART) != -1) { - return ConnectionSource.MYSQL_DIALECT; - } else if (dbName.indexOf(ORACLE_PART) != -1) { - return ConnectionSource.ORACLE_DIALECT; - } else if (dbName.indexOf(MSSQL_PART) != -1) { - return ConnectionSource.MSSQL_DIALECT; - } else if (dbName.indexOf(HSQL_PART) != -1) { - return ConnectionSource.HSQL_DIALECT; - } else { - return ConnectionSource.UNKNOWN_DIALECT; - } - } catch (SQLException sqle) { - // we can't do much here - } - - return dialectCode; - } - - public static SQLDialect getDialectFromCode(int dialectCode) { - SQLDialect sqlDialect = null; - - switch (dialectCode) { - case ConnectionSource.POSTGRES_DIALECT: - sqlDialect = new PostgreSQLDialect(); - - break; - case ConnectionSource.MYSQL_DIALECT: - sqlDialect = new MySQLDialect(); - - break; - case ConnectionSource.ORACLE_DIALECT: - sqlDialect = new OracleDialect(); - - break; - case ConnectionSource.MSSQL_DIALECT: - sqlDialect = new MsSQLDialect(); - - break; - case ConnectionSource.HSQL_DIALECT: - sqlDialect = new HSQLDBDialect(); - - break; - } - return sqlDialect; - } - - /** - * This method handles cases where the - * {@link DatabaseMetaData#supportsGetGeneratedKeys} method is missing in the - * JDBC driver implementation. - */ - public boolean supportsGetGeneratedKeys(DatabaseMetaData meta) { - try { - // - // invoking JDK 1.4 method by reflection - // - return ((Boolean) DatabaseMetaData.class.getMethod("supportsGetGeneratedKeys", null).invoke(meta, null)).booleanValue(); - } catch(Throwable e) { - getLogger().info("Could not call supportsGetGeneratedKeys method. This may be recoverable"); - return false; - } - } - -/** - * This method handles cases where the - * {@link DatabaseMetaData#supportsBatchUpdates} method is missing in the - * JDBC driver implementation. - */ - public boolean supportsBatchUpdates(DatabaseMetaData meta) { - try { - return meta.supportsBatchUpdates(); - } catch(Throwable e) { - getLogger().info("Missing DatabaseMetaData.supportsBatchUpdates method."); - return false; - } - } -} diff --git a/src/main/java/org/apache/log4j/db/dialect/db2.sql b/src/main/java/org/apache/log4j/db/dialect/db2.sql deleted file mode 100644 index 1ff655d9aa..0000000000 --- a/src/main/java/org/apache/log4j/db/dialect/db2.sql +++ /dev/null @@ -1,49 +0,0 @@ -# This SQL script creates the required tables by org.apache.log4j.db.DBAppender and -# org.apache.log4j.db.DBReceiver. -# -# It is intended for IBM DB2 databases. -# -# WARNING WARNING WARNING WARNING -# ================================= -# This SQL script has not been tested on an actual DB2 -# instance. It may contain errors or even invalid SQL -# statements. - -DROP TABLE logging_event_property; -DROP TABLE logging_event_exception; -DROP TABLE logging_event; - -CREATE TABLE logging_event - ( - sequence_number BIGINT NOT NULL, - timestamp BIGINT NOT NULL, - rendered_message VARCHAR(4000) NOT NULL, - logger_name VARCHAR(254) NOT NULL, - level_string VARCHAR(254) NOT NULL, - ndc VARCHAR(4000), - thread_name VARCHAR(254), - reference_flag SMALLINT, - caller_filename VARCHAR(254) NOT NULL, - caller_class VARCHAR(254) NOT NULL, - caller_method VARCHAR(254) NOT NULL, - caller_line CHAR(4) NOT NULL, - event_id INTEGER GENERATED ALWAYS AS IDENTITY (START WITH 1) - ); - -CREATE TABLE logging_event_property - ( - event_id INTEGER NOT NULL, - mapped_key VARCHAR(254) NOT NULL, - mapped_value VARCHAR(1024), - PRIMARY KEY(event_id, mapped_key), - FOREIGN KEY (event_id) REFERENCES logging_event(event_id) - ); - -CREATE TABLE logging_event_exception - ( - event_id INTEGER NOT NULL, - i SMALLINT NOT NULL, - trace_line VARCHAR(254) NOT NULL, - PRIMARY KEY(event_id, i), - FOREIGN KEY (event_id) REFERENCES logging_event(event_id) - ); diff --git a/src/main/java/org/apache/log4j/db/dialect/db2l.sql b/src/main/java/org/apache/log4j/db/dialect/db2l.sql deleted file mode 100644 index c3dd3fe8b3..0000000000 --- a/src/main/java/org/apache/log4j/db/dialect/db2l.sql +++ /dev/null @@ -1,47 +0,0 @@ -# This SQL script creates the required tables by org.apache.log4j.db.DBAppender and -# org.apache.log4j.db.DBReceiver. -# -# It is intended for PostgreSQL databases. - -DROP TABLE logging_event_property; -DROP TABLE logging_event_exception; -DROP TABLE logging_event; - - -CREATE SEQUENCE logging_event_id_seq MINVALUE 1 START 1; - - -CREATE TABLE logging_event - ( - sequence_number BIGINT NOT NULL, - timestamp BIGINT NOT NULL, - rendered_message TEXT NOT NULL, - logger_name VARCHAR(254) NOT NULL, - level_string VARCHAR(254) NOT NULL, - ndc TEXT, - thread_name VARCHAR(254), - reference_flag SMALLINT, - caller_filename VARCHAR(254) NOT NULL, - caller_class VARCHAR(254) NOT NULL, - caller_method VARCHAR(254) NOT NULL, - caller_line CHAR(4) NOT NULL, - event_id INT IDENTITY GENERATED ALWAYS PRIMARY KEY - ); - -CREATE TABLE logging_event_property - ( - event_id INT NOT NULL, - mapped_key VARCHAR(254) NOT NULL, - mapped_value VARCHAR(1024), - PRIMARY KEY(event_id, mapped_key), - FOREIGN KEY (event_id) REFERENCES logging_event(event_id) - ); - -CREATE TABLE logging_event_exception - ( - event_id INT NOT NULL, - i SMALLINT NOT NULL, - trace_line VARCHAR(254) NOT NULL, - PRIMARY KEY(event_id, i), - FOREIGN KEY (event_id) REFERENCES logging_event(event_id) - ); diff --git a/src/main/java/org/apache/log4j/db/dialect/hsqldb.sql b/src/main/java/org/apache/log4j/db/dialect/hsqldb.sql deleted file mode 100644 index cc841f5ae1..0000000000 --- a/src/main/java/org/apache/log4j/db/dialect/hsqldb.sql +++ /dev/null @@ -1,46 +0,0 @@ -// This SQL script creates the required tables by -// org.apache.log4j.db.DBAppender and org.apache.log4j.db.DBReceiver. -// -// It is intended for HSQLDB. -// - -DROP TABLE logging_event_exception IF EXISTS; -DROP TABLE logging_event_property IF EXISTS; -DROP TABLE logging_event IF EXISTS; - - -CREATE TABLE logging_event - ( - sequence_number BIGINT NOT NULL, - timestamp BIGINT NOT NULL, - rendered_message LONGVARCHAR NOT NULL, - logger_name VARCHAR NOT NULL, - level_string VARCHAR NOT NULL, - ndc LONGVARCHAR, - thread_name VARCHAR, - reference_flag SMALLINT, - caller_filename VARCHAR, - caller_class VARCHAR, - caller_method VARCHAR, - caller_line CHAR(4), - event_id INT NOT NULL IDENTITY - ); - - -CREATE TABLE logging_event_property - ( - event_id INT NOT NULL, - mapped_key VARCHAR(254) NOT NULL, - mapped_value LONGVARCHAR, - PRIMARY KEY(event_id, mapped_key), - FOREIGN KEY (event_id) REFERENCES logging_event(event_id) - ); - -CREATE TABLE logging_event_exception - ( - event_id INT NOT NULL, - i SMALLINT NOT NULL, - trace_line VARCHAR NOT NULL, - PRIMARY KEY(event_id, i), - FOREIGN KEY (event_id) REFERENCES logging_event(event_id) - ); diff --git a/src/main/java/org/apache/log4j/db/dialect/mssql.sql b/src/main/java/org/apache/log4j/db/dialect/mssql.sql deleted file mode 100644 index d041b34cd5..0000000000 --- a/src/main/java/org/apache/log4j/db/dialect/mssql.sql +++ /dev/null @@ -1,45 +0,0 @@ --- This SQL script creates the required tables by org.apache.log4j.db.DBAppender and --- org.apache.log4j.db.DBReceiver. --- --- It is intended for MS SQL Server databases. This has been tested with version 7.0. - -DROP TABLE logging_event_property -DROP TABLE logging_event_exception -DROP TABLE logging_event - -CREATE TABLE logging_event - ( - sequence_number DECIMAL(20) NOT NULL, - timestamp DECIMAL(20) NOT NULL, - rendered_message VARCHAR(4000) NOT NULL, - logger_name VARCHAR(254) NOT NULL, - level_string VARCHAR(254) NOT NULL, - ndc VARCHAR(4000), - thread_name VARCHAR(254), - reference_flag SMALLINT, - caller_filename VARCHAR(254) NOT NULL, - caller_class VARCHAR(254) NOT NULL, - caller_method VARCHAR(254) NOT NULL, - caller_line CHAR(4) NOT NULL, - event_id INT NOT NULL identity, - PRIMARY KEY(event_id) - ) - -CREATE TABLE logging_event_property - ( - event_id INT NOT NULL, - mapped_key VARCHAR(254) NOT NULL, - mapped_value VARCHAR(1024), - PRIMARY KEY(event_id, mapped_key), - FOREIGN KEY (event_id) REFERENCES logging_event(event_id) - ) - -CREATE TABLE logging_event_exception - ( - event_id INT NOT NULL, - i SMALLINT NOT NULL, - trace_line VARCHAR(254) NOT NULL, - PRIMARY KEY(event_id, i), - FOREIGN KEY (event_id) REFERENCES logging_event(event_id) - ) - diff --git a/src/main/java/org/apache/log4j/db/dialect/mysql.sql b/src/main/java/org/apache/log4j/db/dialect/mysql.sql deleted file mode 100644 index 34910e6dbb..0000000000 --- a/src/main/java/org/apache/log4j/db/dialect/mysql.sql +++ /dev/null @@ -1,54 +0,0 @@ -# This SQL script creates the required tables by org.apache.log4j.db.DBAppender and -# org.apache.log4j.db.DBReceiver. -# -# It is intended for MySQL databases. It has been tested on MySQL 4.1.1 with -# INNODB tables. - - -BEGIN; -DROP TABLE IF EXISTS logging_event_property; -DROP TABLE IF EXISTS logging_event_exception; -DROP TABLE IF EXISTS logging_event; -COMMIT; - - -BEGIN; -CREATE TABLE logging_event - ( - sequence_number BIGINT NOT NULL, - timestamp BIGINT NOT NULL, - rendered_message TEXT NOT NULL, - logger_name VARCHAR(254) NOT NULL, - level_string VARCHAR(254) NOT NULL, - ndc TEXT, - thread_name VARCHAR(254), - reference_flag SMALLINT, - caller_filename VARCHAR(254) NOT NULL, - caller_class VARCHAR(254) NOT NULL, - caller_method VARCHAR(254) NOT NULL, - caller_line CHAR(4) NOT NULL, - event_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY - ); -COMMIT; - -BEGIN; -CREATE TABLE logging_event_property - ( - event_id INT NOT NULL, - mapped_key VARCHAR(254) NOT NULL, - mapped_value TEXT, - PRIMARY KEY(event_id, mapped_key), - FOREIGN KEY (event_id) REFERENCES logging_event(event_id) - ); -COMMIT; - -BEGIN; -CREATE TABLE logging_event_exception - ( - event_id INT NOT NULL, - i SMALLINT NOT NULL, - trace_line VARCHAR(254) NOT NULL, - PRIMARY KEY(event_id, i), - FOREIGN KEY (event_id) REFERENCES logging_event(event_id) - ); -COMMIT; \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/db/dialect/oracle.sql b/src/main/java/org/apache/log4j/db/dialect/oracle.sql deleted file mode 100644 index 81fe9c5519..0000000000 --- a/src/main/java/org/apache/log4j/db/dialect/oracle.sql +++ /dev/null @@ -1,61 +0,0 @@ --- This SQL script creates the required tables by org.apache.log4j.db.DBAppender and --- org.apache.log4j.db.DBReceiver. --- --- It is intended for Oracle databases. - --- Tested successfully on Oracle9i Release 9.2.0.3.0 by James Stauffer --- Tested successfully on Oracle9i Release by Elias Ross - --- The following lines are useful in cleaning any previous tables - ---drop TRIGGER logging_event_id_seq_trig; ---drop SEQUENCE logging_event_id_seq; ---drop table logging_event_property; ---drop table logging_event_exception; ---drop table logging_event; - -CREATE SEQUENCE logging_event_id_seq MINVALUE 1 START WITH 1; - -CREATE TABLE logging_event - ( - sequence_number NUMBER(20) NOT NULL, - timestamp NUMBER(20) NOT NULL, - rendered_message VARCHAR2(4000) NOT NULL, - logger_name VARCHAR2(254) NOT NULL, - level_string VARCHAR2(254) NOT NULL, - ndc VARCHAR2(4000), - thread_name VARCHAR2(254), - reference_flag NUMBER(5), - caller_filename VARCHAR2(254) NOT NULL, - caller_class VARCHAR2(254) NOT NULL, - caller_method VARCHAR2(254) NOT NULL, - caller_line CHAR(4) NOT NULL, - event_id NUMBER(10) PRIMARY KEY - ); - -CREATE OR REPLACE TRIGGER logging_event_id_seq_trig -BEFORE INSERT ON logging_event -FOR EACH ROW -BEGIN - SELECT logging_event_id_seq.nextval - INTO :new.sequence_number$ FROM dual -END; - -CREATE TABLE logging_event_property - ( - event_id NUMBER(10) NOT NULL, - mapped_key VARCHAR2(254) NOT NULL, - mapped_value VARCHAR2(1024), - PRIMARY KEY(event_id, mapped_key), - FOREIGN KEY (event_id) REFERENCES logging_event(event_id) - ); - -CREATE TABLE logging_event_exception - ( - event_id NUMBER(10) NOT NULL, - i NUMBER(5) NOT NULL, - trace_line VARCHAR2(254) NOT NULL, - PRIMARY KEY(event_id, i), - FOREIGN KEY (event_id) REFERENCES logging_event(event_id) - ); - \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/db/dialect/postgresql.sql b/src/main/java/org/apache/log4j/db/dialect/postgresql.sql deleted file mode 100644 index 464a6acb49..0000000000 --- a/src/main/java/org/apache/log4j/db/dialect/postgresql.sql +++ /dev/null @@ -1,48 +0,0 @@ -# This SQL script creates the required tables by org.apache.log4j.db.DBAppender and -# org.apache.log4j.db.DBReceiver. -# -# It is intended for PostgreSQL databases. - -DROP TABLE logging_event_property; -DROP TABLE logging_event_exception; -DROP SEQUENCE logging_event_id_seq; -DROP TABLE logging_event; - - -CREATE SEQUENCE logging_event_id_seq MINVALUE 1 START 1; - - -CREATE TABLE logging_event - ( - sequence_number BIGINT NOT NULL, - timestamp BIGINT NOT NULL, - rendered_message TEXT NOT NULL, - logger_name VARCHAR(254) NOT NULL, - level_string VARCHAR(254) NOT NULL, - ndc TEXT, - thread_name VARCHAR(254), - reference_flag SMALLINT, - caller_filename VARCHAR(254) NOT NULL, - caller_class VARCHAR(254) NOT NULL, - caller_method VARCHAR(254) NOT NULL, - caller_line CHAR(4) NOT NULL, - event_id INT DEFAULT nextval('logging_event_id_seq') PRIMARY KEY - ); - -CREATE TABLE logging_event_property - ( - event_id INT NOT NULL, - mapped_key VARCHAR(254) NOT NULL, - mapped_value VARCHAR(1024), - PRIMARY KEY(event_id, mapped_key), - FOREIGN KEY (event_id) REFERENCES logging_event(event_id) - ); - -CREATE TABLE logging_event_exception - ( - event_id INT NOT NULL, - i SMALLINT NOT NULL, - trace_line VARCHAR(254) NOT NULL, - PRIMARY KEY(event_id, i), - FOREIGN KEY (event_id) REFERENCES logging_event(event_id) - ); diff --git a/src/main/java/org/apache/log4j/db/package.html b/src/main/java/org/apache/log4j/db/package.html deleted file mode 100644 index 805ed88311..0000000000 --- a/src/main/java/org/apache/log4j/db/package.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - -

    The org.apache.log4j.db package provides means to append logging events -into various databases. The persisted data can be later read back using -{@link org.apache.log4j.db.DBReceiver}. -

    - -

    Most popular database systems, such as PostgreSQL, MySQL, Oracle, DB2 and MsSQL -are supported. -

    - -

    Just as importantly, the way for obtaining JDBC connections is pluggable. Connections can -be obtained through the tradinal way of DriverManager, or alternatively as a DataSource. -A DataSource can be instantiated directly or it can obtained through JNDI. -

    - - - diff --git a/src/main/java/org/apache/log4j/filter/AndFilter.java b/src/main/java/org/apache/log4j/filter/AndFilter.java deleted file mode 100644 index 66cb863245..0000000000 --- a/src/main/java/org/apache/log4j/filter/AndFilter.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.filter; - -import org.apache.log4j.spi.Filter; -import org.apache.log4j.spi.LoggingEvent; - - -/** - * A filter that 'and's the results of any number of contained filters together. - * - * For the filter to process events, all contained filters must return Filter.ACCEPT. - * - * If the contained filters do not return Filter.ACCEPT, Filter.NEUTRAL is returned. - * - * If acceptOnMatch is set to true, Filter.ACCEPT is returned. - * If acceptOnMatch is set to false, Filter.DENY is returned. - * - * Here is an example config that will accept only events that contain BOTH - * a DEBUG level AND 'test' in the message: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * To accept all events EXCEPT those events that contain a - * DEBUG level and 'test' in the message: - * change the AndFilter's acceptOnMatch param to false and remove the DenyAllFilter - * - * NOTE: If you are defining a filter that is only relying on logging event content - * (no external or filter-managed state), you could opt instead - * to use an ExpressionFilter with one of the following expressions: - * - * LEVEL == DEBUG && MSG ~= 'test' - * or - * ! ( LEVEL == DEBUG && MSG ~= 'test' ) - * - * @author Scott Deboy sdeboy@apache.org - */ -public class AndFilter extends Filter { - Filter headFilter = null; - Filter tailFilter = null; - boolean acceptOnMatch = true; - - public void activateOptions() { - } - - public void addFilter(Filter filter) { - System.out.println("add"+filter); - if (headFilter == null) { - headFilter = filter; - tailFilter = filter; - } else { - tailFilter.setNext(filter); - } - } - - public void setAcceptOnMatch(boolean acceptOnMatch) { - this.acceptOnMatch = acceptOnMatch; - } - /** - * If this event does not already contain location information, - * evaluate the event against the expression. - * - * If the expression evaluates to true, generate a LocationInfo instance - * by creating an exception and set this LocationInfo on the event. - * - * Returns {@link Filter#NEUTRAL} - */ - public int decide(LoggingEvent event) { - boolean accepted = true; - Filter f = headFilter; - while (f != null) { - accepted = accepted && (Filter.ACCEPT == f.decide(event)); - f = f.getNext(); - } - if (accepted) { - if(acceptOnMatch) { - return Filter.ACCEPT; - } - return Filter.DENY; - } - return Filter.NEUTRAL; - } -} diff --git a/src/main/java/org/apache/log4j/filter/DenyAllFilter.java b/src/main/java/org/apache/log4j/filter/DenyAllFilter.java deleted file mode 100644 index 436bb50efd..0000000000 --- a/src/main/java/org/apache/log4j/filter/DenyAllFilter.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.filter; - -import org.apache.log4j.spi.Filter; -import org.apache.log4j.spi.LoggingEvent; - - -/** - This filter drops all logging events. - -

    You can add this filter to the end of a filter chain to - switch from the default "accept all unless instructed otherwise" - filtering behaviour to a "deny all unless instructed otherwise" - behaviour. - - - @author Ceki Gülcü - - @since 0.9.0 */ -public class DenyAllFilter extends Filter { - - /** - Returns null as there are no options. - - @deprecated We now use JavaBeans introspection to configure - components. Options strings are no longer needed. - */ - public - String[] getOptionStrings() { - return null; - } - - - /** - No options to set. - - @deprecated Use the setter method for the option directly instead - of the generic setOption method. - */ - public - void setOption(String key, String value) { - } - - /** - Always returns the integer constant {@link Filter#DENY} - regardless of the {@link LoggingEvent} parameter. - - @param event The LoggingEvent to filter. - @return Always returns {@link Filter#DENY}. - */ - public - int decide(LoggingEvent event) { - return Filter.DENY; - } -} - diff --git a/src/main/java/org/apache/log4j/filter/ExpressionFilter.java b/src/main/java/org/apache/log4j/filter/ExpressionFilter.java deleted file mode 100644 index f5b12fd66b..0000000000 --- a/src/main/java/org/apache/log4j/filter/ExpressionFilter.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.filter; - -import org.apache.log4j.rule.ExpressionRule; -import org.apache.log4j.rule.Rule; -import org.apache.log4j.spi.Filter; -import org.apache.log4j.spi.LoggingEvent; - - -/** - * A filter supporting complex expressions - supports both infix and postfix - * expressions (infix expressions must first be converted to postfix prior - * to processing). - *

    - *

    See org.apache.log4j.chainsaw.LoggingEventFieldResolver.java - * for the correct names for logging event fields - * used when building expressions. - *

    - *

    See org.apache.log4j.chainsaw.rule package - * for a list of available - * rules which can be applied using the expression syntax. - *

    - *

    See org.apache.log4j.chainsaw.RuleFactory for the symbols - * used to activate the corresponding rules. - *

    - * NOTE: Grouping using parentheses is supported - - * all tokens must be separated by spaces, and - * operands which contain spaces are not yet supported. - *

    - * Example: - *

    - * In order to build a filter that displays all messages with - * infomsg-45 or infomsg-44 in the message, - * as well as all messages with a level of WARN or higher, - * build an expression using - * the LikeRule (supports ORO-based regular expressions) and the InequalityRule. - * ( MSG LIKE infomsg-4[4,5] ) && ( LEVEL >= WARN ) - *

    - * Three options are required: - * Expression - the expression to match - * ConvertInFixToPostFix - convert from infix to posfix (default true) - * AcceptOnMatch - true or false (default true) - *

    - * Meaning of AcceptToMatch: - * If there is a match between the value of the - * Expression option and the {@link LoggingEvent} and AcceptOnMatch is true, - * the {@link #decide} method returns {@link Filter#ACCEPT}. - *

    - * If there is a match between the value of the - * Expression option and the {@link LoggingEvent} and AcceptOnMatch is false, - * {@link Filter#DENY} is returned. - *

    - * If there is no match, {@link Filter#NEUTRAL} is returned. - * - * @author Scott Deboy sdeboy@apache.org - */ -public class ExpressionFilter extends Filter { - /** - * accept on match. - */ - boolean acceptOnMatch = true; - /** - * Convert in-fix to post-fix. - */ - boolean convertInFixToPostFix = true; - /** - * Expression. - */ - String expression; - /** - * Evaluated rule. - */ - Rule expressionRule; - - /** - * {@inheritDoc} - */ - public void activateOptions() { - expressionRule = - ExpressionRule.getRule(expression, !convertInFixToPostFix); - } - - /** - * Set exp. - * @param exp exp. - */ - public void setExpression(final String exp) { - this.expression = exp; - } - - /** - * Get expression. - * @return expression. - */ - public String getExpression() { - return expression; - } - - /** - * Set convert in-fix to post-fix. - * @param newValue new value. - */ - public void setConvertInFixToPostFix(final boolean newValue) { - this.convertInFixToPostFix = newValue; - } - - /** - * Get in-fix to post-fix conversion setting. - * @return true if in-fix expressions are converted to post-fix. - */ - public boolean getConvertInFixToPostFix() { - return convertInFixToPostFix; - } - - /** - * Set whether filter should accept events if they match the expression. - * @param newValue if true, accept on match. - */ - public void setAcceptOnMatch(final boolean newValue) { - this.acceptOnMatch = newValue; - } - - /** - * Gets whether filter accepts matching or non-matching events. - * @return if true, accept matching events. - */ - public boolean getAcceptOnMatch() { - return acceptOnMatch; - } - - /** - * Determines if event matches the filter. - * @param event logging event; - * @return {@link Filter#NEUTRAL} is there is no string match. - */ - public int decide(final LoggingEvent event) { - if (expressionRule.evaluate(event)) { - if (acceptOnMatch) { - return Filter.ACCEPT; - } else { - return Filter.DENY; - } - } - return Filter.NEUTRAL; - } -} diff --git a/src/main/java/org/apache/log4j/filter/LevelMatchFilter.java b/src/main/java/org/apache/log4j/filter/LevelMatchFilter.java deleted file mode 100644 index edbab7bec9..0000000000 --- a/src/main/java/org/apache/log4j/filter/LevelMatchFilter.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.filter; - -import org.apache.log4j.Level; -import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.spi.Filter; -import org.apache.log4j.spi.LoggingEvent; - - -/** - This is a very simple filter based on level matching. - -

    The filter admits two options LevelToMatch and - AcceptOnMatch. If there is an exact match between the value - of the LevelToMatch option and the level of the {@link - org.apache.log4j.spi.LoggingEvent}, then the {@link #decide} method returns {@link - org.apache.log4j.spi.Filter#ACCEPT} in case the AcceptOnMatch option value is set - to true, if it is false then {@link - org.apache.log4j.spi.Filter#DENY} is returned. If there is no match, {@link - org.apache.log4j.spi.Filter#NEUTRAL} is returned. - - @author Ceki Gülcü - - @since 1.2 */ -public class LevelMatchFilter extends Filter { - /** - Do we return ACCEPT when a match occurs. Default is - true. */ - boolean acceptOnMatch = true; - - /** - */ - Level levelToMatch; - - public void setLevelToMatch(String level) { - levelToMatch = OptionConverter.toLevel(level, null); - } - - public String getLevelToMatch() { - return (levelToMatch == null) ? null : levelToMatch.toString(); - } - - public void setAcceptOnMatch(boolean acceptOnMatch) { - this.acceptOnMatch = acceptOnMatch; - } - - public boolean getAcceptOnMatch() { - return acceptOnMatch; - } - - - /** - Return the decision of this filter. - - Returns {@link Filter#NEUTRAL} if the LevelToMatch option - is not set or if there is not match. Otherwise, if there is a - match, then the returned decision is {@link Filter#ACCEPT} if the - AcceptOnMatch property is set to true. The - returned decision is {@link Filter#DENY} if the - AcceptOnMatch property is set to false. - - */ - public int decide(LoggingEvent event) { - if (this.levelToMatch == null) { - return Filter.NEUTRAL; - } - - boolean matchOccured = false; - - if (this.levelToMatch.equals(event.getLevel())) { - matchOccured = true; - } - - if (matchOccured) { - if (this.acceptOnMatch) { - return Filter.ACCEPT; - } else { - return Filter.DENY; - } - } else { - return Filter.NEUTRAL; - } - } -} diff --git a/src/main/java/org/apache/log4j/filter/LevelRangeFilter.java b/src/main/java/org/apache/log4j/filter/LevelRangeFilter.java deleted file mode 100644 index 3d65aa88ee..0000000000 --- a/src/main/java/org/apache/log4j/filter/LevelRangeFilter.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.filter; - -import org.apache.log4j.Level; -import org.apache.log4j.spi.Filter; -import org.apache.log4j.spi.LoggingEvent; - -/** - This is a very simple filter based on level matching, which can be - used to reject messages with priorities outside a certain range. - -

    The filter admits three options LevelMin, LevelMax - and AcceptOnMatch. - -

    If the level of the {@link org.apache.log4j.spi.LoggingEvent} is not between Min and Max - (inclusive), then {@link org.apache.log4j.spi.Filter#DENY} is returned. - -

    If the Logging event level is within the specified range, then if - AcceptOnMatch is true, {@link org.apache.log4j.spi.Filter#ACCEPT} is returned, and if - AcceptOnMatch is false, {@link org.apache.log4j.spi.Filter#NEUTRAL} is returned. - -

    If LevelMinw is not defined, then there is no - minimum acceptable level (ie a level is never rejected for - being too "low"/unimportant). If LevelMax is not - defined, then there is no maximum acceptable level (ie a - level is never rejected for beeing too "high"/important). - -

    Refer to the {@link - org.apache.log4j.AppenderSkeleton#setThreshold setThreshold} method - available to all appenders extending {@link - org.apache.log4j.AppenderSkeleton} for a more convenient way to - filter out events by level. - - @author Simon Kitching - @author based on code by Ceki Gülcü -*/ -public class LevelRangeFilter extends Filter { - - /** - Do we return ACCEPT when a match occurs. Default is - false, so that later filters get run by default */ - boolean acceptOnMatch = false; - - Level levelMin; - Level levelMax; - - - /** - Return the decision of this filter. - */ - public - int decide(LoggingEvent event) { - if(this.levelMin != null) { - if (event.getLevel().isGreaterOrEqual(levelMin) == false) { - // level of event is less than minimum - return Filter.DENY; - } - } - - if(this.levelMax != null) { - if (event.getLevel().toInt() > levelMax.toInt()) { - // level of event is greater than maximum - // Alas, there is no Level.isGreater method. and using - // a combo of isGreaterOrEqual && !Equal seems worse than - // checking the int values of the level objects.. - return Filter.DENY; - } - } - - if (acceptOnMatch) { - // this filter set up to bypass later filters and always return - // accept if level in range - return Filter.ACCEPT; - } - else { - // event is ok for this filter; allow later filters to have a look.. - return Filter.NEUTRAL; - } - } - - /** - Get the value of the LevelMax option. */ - public - Level getLevelMax() { - return levelMax; - } - - - /** - Get the value of the LevelMin option. */ - public - Level getLevelMin() { - return levelMin; - } - - /** - Get the value of the AcceptOnMatch option. - */ - public - boolean getAcceptOnMatch() { - return acceptOnMatch; - } - - /** - Set the LevelMax option. - */ - public - void setLevelMax(Level levelMax) { - this.levelMax = levelMax; - } - - /** - Set the LevelMin option. - */ - public - void setLevelMin(Level levelMin) { - this.levelMin = levelMin; - } - - /** - Set the AcceptOnMatch option. - */ - public - void setAcceptOnMatch(boolean acceptOnMatch) { - this.acceptOnMatch = acceptOnMatch; - } -} - diff --git a/src/main/java/org/apache/log4j/filter/LocationInfoFilter.java b/src/main/java/org/apache/log4j/filter/LocationInfoFilter.java deleted file mode 100644 index 74bc485767..0000000000 --- a/src/main/java/org/apache/log4j/filter/LocationInfoFilter.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.filter; - -import org.apache.log4j.rule.ExpressionRule; -import org.apache.log4j.rule.Rule; -import org.apache.log4j.spi.Filter; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.LocationInfo; - - -/** - * Location information is usually specified at the appender level - - * all events associated - * with an appender either create and parse stack traces or they do not. - * This is an expensive operation and in some cases not needed - * for all events associated with an appender. - * - * This filter creates event-level location information only - * if the provided expression evaluates to true. - * - * For information on expression syntax, - * see org.apache.log4j.rule.ExpressionRule - * - * @author Scott Deboy sdeboy@apache.org - */ -public class LocationInfoFilter extends Filter { - /** - * Convert to in-fix to post-fix. - */ - boolean convertInFixToPostFix = true; - /** - * Expression. - */ - String expression; - /** - * Compiled expression. - */ - Rule expressionRule; - /** - HACK: Category is the last of the internal layers - - pass this in as the class name - in order for parsing to work correctly. - */ - private String className = "org.apache.log4j.Category"; - - /** - * {@inheritDoc} - */ - public void activateOptions() { - expressionRule = - ExpressionRule.getRule(expression, !convertInFixToPostFix); - } - - /** - * Set expression. - * @param exp expression. - */ - public void setExpression(final String exp) { - this.expression = exp; - } - - /** - * Get expression. - * @return expression. - */ - public String getExpression() { - return expression; - } - - /** - * Set whether in-fix expressions should be converted to post-fix. - * @param newValue if true, convert/ - */ - public void setConvertInFixToPostFix(final boolean newValue) { - this.convertInFixToPostFix = newValue; - } - - /** - * Set whether in-fix expressions should be converted to post-fix. - * @return if true, expressions are converted. - */ - public boolean getConvertInFixToPostFix() { - return convertInFixToPostFix; - } - - /** - * If this event does not already contain location information, - * evaluate the event against the expression. - * - * If the expression evaluates to true, generate a LocationInfo instance - * by creating an exception and set this LocationInfo on the event. - * - * @param event event - * @return Filter.NEUTRAL. - */ - public int decide(final LoggingEvent event) { - if (!event.locationInformationExists()) { - if (expressionRule.evaluate(event)) { - Throwable t = new Exception(); - event.setLocationInformation(new LocationInfo(t, className)); - } - } - return Filter.NEUTRAL; - } -} diff --git a/src/main/java/org/apache/log4j/filter/LoggerMatchFilter.java b/src/main/java/org/apache/log4j/filter/LoggerMatchFilter.java deleted file mode 100644 index 64766ea409..0000000000 --- a/src/main/java/org/apache/log4j/filter/LoggerMatchFilter.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.filter; - -import org.apache.log4j.spi.Filter; -import org.apache.log4j.spi.LoggingEvent; - - -/** - This is a very simple filter based on logger name matching. - -

    The filter admits two options LoggerToMatch and - AcceptOnMatch. If there is an exact match between the value - of the LoggerToMatch option and the logger of the {@link - org.apache.log4j.spi.LoggingEvent}, then the {@link #decide} method returns {@link - org.apache.log4j.spi.Filter#ACCEPT} in case the AcceptOnMatch option value is set - to true, if it is false then {@link - org.apache.log4j.spi.Filter#DENY} is returned. If there is no match, {@link - org.apache.log4j.spi.Filter#NEUTRAL} is returned. A loggerToMatch of "root" - matches both the root logger and a logger named "root". - - @since 1.3 */ -public class LoggerMatchFilter extends Filter { - /** - Do we return ACCEPT when a match occurs. Default is - true. */ - private boolean acceptOnMatch = true; - - /** - * Logger name, may be null or empty in which case it matches root. - */ - private String loggerToMatch = "root"; - - /** - * Sets logger name. - * @param logger logger name. - */ - public void setLoggerToMatch(final String logger) { - if (logger == null) { - loggerToMatch = "root"; - } else { - loggerToMatch = logger; - } - } - - /** - * Gets logger name. - * @return logger name. - */ - public String getLoggerToMatch() { - return loggerToMatch; - } - - /** - * Sets whether a match should result in acceptance. - * @param acceptOnMatch if true, accept if logger name matches, otherwise reject. - */ - public void setAcceptOnMatch(final boolean acceptOnMatch) { - this.acceptOnMatch = acceptOnMatch; - } - - /** - * Gets whether a match should result in acceptance. - * @return true if event is accepted if logger name matches. - */ - public boolean getAcceptOnMatch() { - return acceptOnMatch; - } - - - /** - * {@inheritDoc} - */ - public int decide(final LoggingEvent event) { - boolean matchOccured = loggerToMatch.equals(event.getLoggerName()); - if (matchOccured) { - if (this.acceptOnMatch) { - return Filter.ACCEPT; - } else { - return Filter.DENY; - } - } else { - return Filter.NEUTRAL; - } - } -} diff --git a/src/main/java/org/apache/log4j/filter/MapFilter.java b/src/main/java/org/apache/log4j/filter/MapFilter.java deleted file mode 100644 index 3e7fec3817..0000000000 --- a/src/main/java/org/apache/log4j/filter/MapFilter.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.filter; - -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Map; -import org.apache.log4j.spi.Filter; -import org.apache.log4j.spi.LoggingEvent; - -public class MapFilter extends Filter { - - /** - * NOTE: This filter modifies logging events by adding properties to the event. - * - * The object passed in as the event message must implement java.util.Map. - * - * This filter converts the event message (a Map) into properties on the event. - * - * If the map holds an entry with a key of "message", the value of the entry is used - * as the rendered message. - * - * @since 1.3 - */ - public int decide(LoggingEvent event) { - Map properties = event.getProperties(); - Hashtable eventProps = null; - if (properties == null) { - eventProps = new Hashtable(); - } else { - eventProps = new Hashtable(properties); - } - - if (event.getMessage() instanceof Map) { - for (Iterator iter = ((Map)event.getMessage()).entrySet().iterator();iter.hasNext();) { - Map.Entry entry = (Map.Entry)iter.next(); - if ("message".equalsIgnoreCase(entry.getKey().toString())) { - event.setRenderedMessage(entry.getValue().toString()); - } else { - eventProps.put(entry.getKey(), entry.getValue()); - } - } - event.setProperties(eventProps); - } - return Filter.NEUTRAL; - } -} diff --git a/src/main/java/org/apache/log4j/filter/PropertyFilter.java b/src/main/java/org/apache/log4j/filter/PropertyFilter.java deleted file mode 100644 index 72b668effd..0000000000 --- a/src/main/java/org/apache/log4j/filter/PropertyFilter.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.filter; - -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Map; -import java.util.StringTokenizer; - -import org.apache.log4j.spi.Filter; -import org.apache.log4j.spi.LoggingEvent; - -/** - * NOTE: This filter modifies logging events by adding properties to the event. - * - * The 'properties' param is converted to event properties, which are - * set on every event processed by the filter. - * - * Individual properties are only set if they do not already exist on the - * logging event (will not override existing properties). - * - * This class relies on the convention that property name/value pairs are - * equals-symbol delimited, and each name/value pair is comma-delimited - * - * Example properties param: - * somename=somevalue,anothername=anothervalue,thirdname=third value - * - * @since 1.3 - */ -public class PropertyFilter extends Filter { - private Hashtable properties; - public void setProperties(String props) { - properties = parseProperties(props); - } - - public int decide(LoggingEvent event) { - Map eventProps = event.getProperties(); - if (eventProps == null) { - event.setProperties(new Hashtable(properties)); - } else { - //only add properties that don't already exist - for (Iterator iter = properties.keySet().iterator();iter.hasNext();) { - Object key = iter.next(); - if (!(eventProps.containsKey(key))) { - eventProps.put(key, properties.get(key)); - } - } - } - return Filter.NEUTRAL; - } - - private Hashtable parseProperties(String props) { - Hashtable hashTable = new Hashtable(); - StringTokenizer pairs = new StringTokenizer(props, ","); - while (pairs.hasMoreTokens()) { - StringTokenizer entry = new StringTokenizer(pairs.nextToken(), "="); - hashTable.put(entry.nextElement().toString().trim(), entry.nextElement().toString().trim()); - } - return hashTable; - } -} diff --git a/src/main/java/org/apache/log4j/filter/ReflectionFilter.java b/src/main/java/org/apache/log4j/filter/ReflectionFilter.java deleted file mode 100644 index e9c697b06e..0000000000 --- a/src/main/java/org/apache/log4j/filter/ReflectionFilter.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.filter; - -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.lang.reflect.InvocationTargetException; -import java.util.Hashtable; -import java.util.Map; - -import org.apache.log4j.spi.Filter; -import org.apache.log4j.spi.LoggingEvent; - -public class ReflectionFilter extends Filter { - - /** - * NOTE: This filter modifies logging events by adding - * properties to the event. - * - * The object passed in as the message must provide a message via toString - * or provide a 'message' property, which will be set as the rendered message. - * - * This ReflectionFilter uses the JavaBeans BeanInfo and PropertyDescriptor mechanisms to discover - * readMethods available on the 'message' object provided by the event. - * - * For each method available on the object via the BeanInfo PropertyDescriptors, the method is executed - * and a property is added to the event, using the results of the method call as the value - * and the method name as the key. - * - * @since 1.3 - */ - public int decide(LoggingEvent event) { - Map properties = event.getProperties(); - Hashtable eventProps = null; - if (properties == null) { - eventProps = new Hashtable(); - } else { - eventProps = new Hashtable(properties); - } - - //ignore strings and the object class properties - if (!(event.getMessage() instanceof String)) { - PropertyDescriptor[] props; - try { - props = Introspector.getBeanInfo(event.getMessage().getClass(), Object.class).getPropertyDescriptors(); - for (int i=0;iThe filter admits two options StringToMatch and - AcceptOnMatch. If there is a match between the value of the - StringToMatch option and the message of the {@link LoggingEvent}, - then the {@link #decide(LoggingEvent)} method returns - {@link org.apache.log4j.spi.Filter#ACCEPT} if - the AcceptOnMatch option value is true, if it is false then - {@link org.apache.log4j.spi.Filter#DENY} is returned. If there is no match, {@link - org.apache.log4j.spi.Filter#NEUTRAL} is returned. - - @author Ceki Gülcü - - @since 0.9.0 -*/ -public class StringMatchFilter extends Filter { - - boolean acceptOnMatch = true; - String stringToMatch; - - public - void setStringToMatch(String s) { - stringToMatch = s; - } - - public - String getStringToMatch() { - return stringToMatch; - } - - public - void setAcceptOnMatch(boolean acceptOnMatch) { - this.acceptOnMatch = acceptOnMatch; - } - - public - boolean getAcceptOnMatch() { - return acceptOnMatch; - } - - /** - Returns {@link Filter#NEUTRAL} is there is no string match. - */ - public - int decide(LoggingEvent event) { - String msg = event.getRenderedMessage(); - - if(msg == null || stringToMatch == null) - return Filter.NEUTRAL; - - - if( msg.indexOf(stringToMatch) == -1 ) { - return Filter.NEUTRAL; - } else { // we've got a match - if(acceptOnMatch) { - return Filter.ACCEPT; - } else { - return Filter.DENY; - } - } - } -} diff --git a/src/main/java/org/apache/log4j/helpers/AbsoluteTimeDateFormat.java b/src/main/java/org/apache/log4j/helpers/AbsoluteTimeDateFormat.java index bfd1b09b2e..98472ee38f 100644 --- a/src/main/java/org/apache/log4j/helpers/AbsoluteTimeDateFormat.java +++ b/src/main/java/org/apache/log4j/helpers/AbsoluteTimeDateFormat.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,100 +17,131 @@ package org.apache.log4j.helpers; -import java.text.DateFormat; -import java.text.FieldPosition; -import java.text.ParsePosition; -import java.text.SimpleDateFormat; - import java.util.Date; +import java.util.Calendar; import java.util.TimeZone; +import java.text.FieldPosition; +import java.text.ParsePosition; +import java.text.DateFormat; /** Formats a {@link Date} in the format "HH:mm:ss,SSS" for example, "15:49:37,459". - + @author Ceki Gülcü - @author Andrew Vajoczki + @author Andrew Vajoczki @since 0.7.5 - @deprecated use java.text.SimpleDateFormat to perform date conversion - or use org.apache.log4j.helpers.CachedDateFormat to optimize - high-frequency date formatting. */ public class AbsoluteTimeDateFormat extends DateFormat { - /** - String constant used to specify the Absolute time and date format. - */ - public static final String ABS_TIME_DATE_FORMAT = "ABSOLUTE"; + private static final long serialVersionUID = -388856345976723342L; /** - String constant used to specify the "Date and Time" date format. - */ - public static final String DATE_AND_TIME_DATE_FORMAT = "DATE"; + String constant used to specify {@link + org.apache.log4j.helpers.AbsoluteTimeDateFormat} in layouts. Current + value is ABSOLUTE. */ + public final static String ABS_TIME_DATE_FORMAT = "ABSOLUTE"; /** - String constant used to specify the ISO8601 format. + String constant used to specify {@link + org.apache.log4j.helpers.DateTimeDateFormat} in layouts. Current + value is DATE. */ - public static final String ISO8601_DATE_FORMAT = "ISO8601"; + public final static String DATE_AND_TIME_DATE_FORMAT = "DATE"; /** - Equivalent SimpleDateFormat pattern. - */ - public static final String PATTERN = "HH:mm:ss,SSS"; - - /** - * SimpleDateFormat used to perform format requests. - */ - private final SimpleDateFormat format; + String constant used to specify {@link + org.apache.log4j.helpers.ISO8601DateFormat} in layouts. Current + value is ISO8601. + */ + public final static String ISO8601_DATE_FORMAT = "ISO8601"; - /** - * Create a new instance of AbsoluteTimeDateFormat. - */ - public AbsoluteTimeDateFormat() { - format = new SimpleDateFormat(PATTERN); + public + AbsoluteTimeDateFormat() { + setCalendar(Calendar.getInstance()); + } + + public + AbsoluteTimeDateFormat(TimeZone timeZone) { + setCalendar(Calendar.getInstance(timeZone)); } + private static long previousTime; + private static char[] previousTimeWithoutMillis = new char[9]; // "HH:mm:ss." + /** - * Create a new instance of AbsoluteTimeDateFormat. - * @param timeZone time zone used in conversion, may not be null. - */ - public AbsoluteTimeDateFormat(final TimeZone timeZone) { - format = new SimpleDateFormat(PATTERN); - format.setTimeZone(timeZone); - } + Appends to sbuf the time in the format + "HH:mm:ss,SSS" for example, "15:49:37,459" - /** - * Create a new instance of AbsoluteTimeDateFormat. - * @param pattern SimpleDateFormat pattern. - */ - protected AbsoluteTimeDateFormat(final String pattern) { - format = new SimpleDateFormat(pattern); + @param date the date to format + @param sbuf the string buffer to write to + @param fieldPosition remains untouched + */ + public + StringBuffer format(Date date, StringBuffer sbuf, + FieldPosition fieldPosition) { + + long now = date.getTime(); + int millis = (int)(now % 1000); + + if ((now - millis) != previousTime || previousTimeWithoutMillis[0] == 0) { + // We reach this point at most once per second + // across all threads instead of each time format() + // is called. This saves considerable CPU time. + + calendar.setTime(date); + + int start = sbuf.length(); + + int hour = calendar.get(Calendar.HOUR_OF_DAY); + if(hour < 10) { + sbuf.append('0'); + } + sbuf.append(hour); + sbuf.append(':'); + + int mins = calendar.get(Calendar.MINUTE); + if(mins < 10) { + sbuf.append('0'); + } + sbuf.append(mins); + sbuf.append(':'); + + int secs = calendar.get(Calendar.SECOND); + if(secs < 10) { + sbuf.append('0'); + } + sbuf.append(secs); + sbuf.append(','); + + // store the time string for next time to avoid recomputation + sbuf.getChars(start, sbuf.length(), previousTimeWithoutMillis, 0); + + previousTime = now - millis; } - - /** - * Create a new instance of AbsoluteTimeDateFormat. - * @param pattern SimpleDateFormat pattern. - * @param timeZone time zone used in conversion, may not be null. - */ - protected AbsoluteTimeDateFormat(final String pattern, - final TimeZone timeZone) { - format = new SimpleDateFormat(pattern); - format.setTimeZone(timeZone); + else { + sbuf.append(previousTimeWithoutMillis); } + - /** - * {@inheritDoc} - */ - public StringBuffer format( - Date date, StringBuffer sbuf, FieldPosition fieldPosition) { - return format.format(date, sbuf, fieldPosition); + + if(millis < 100) { + sbuf.append('0'); + } + if(millis < 10) { + sbuf.append('0'); + } + + sbuf.append(millis); + return sbuf; } /** - * {@inheritDoc} + This method does not do anything but return null. */ - public Date parse(String s, ParsePosition pos) { - return format.parse(s, pos); - } + public + Date parse(String s, ParsePosition pos) { + return null; + } } diff --git a/src/main/java/org/apache/log4j/helpers/AppenderAttachableImpl.java b/src/main/java/org/apache/log4j/helpers/AppenderAttachableImpl.java index 7d40478e70..4aae5c1b0e 100644 --- a/src/main/java/org/apache/log4j/helpers/AppenderAttachableImpl.java +++ b/src/main/java/org/apache/log4j/helpers/AppenderAttachableImpl.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,13 +17,12 @@ package org.apache.log4j.helpers; -import org.apache.log4j.Appender; import org.apache.log4j.spi.AppenderAttachable; import org.apache.log4j.spi.LoggingEvent; -import java.util.Enumeration; +import org.apache.log4j.Appender; import java.util.Vector; - +import java.util.Enumeration; /** A straightforward implementation of the {@link AppenderAttachable} @@ -31,155 +31,156 @@ @author Ceki Gülcü @since version 0.9.1 */ public class AppenderAttachableImpl implements AppenderAttachable { + /** Array of appenders. */ - protected Vector appenderList; + protected Vector appenderList; /** Attach an appender. If the appender is already in the list in won't be added again. */ - public void addAppender(Appender newAppender) { + public + void addAppender(Appender newAppender) { // Null values for newAppender parameter are strictly forbidden. - if (newAppender == null) { - return; + if(newAppender == null) { + return; } - - if (appenderList == null) { + + if(appenderList == null) { appenderList = new Vector(1); } - - if (!appenderList.contains(newAppender)) { - appenderList.addElement(newAppender); + if(!appenderList.contains(newAppender)) { + appenderList.addElement(newAppender); } } /** Call the doAppend method on all attached appenders. */ - public int appendLoopOnAppenders(LoggingEvent event) { + public + int appendLoopOnAppenders(LoggingEvent event) { int size = 0; Appender appender; - if (appenderList != null) { + if(appenderList != null) { size = appenderList.size(); - - for (int i = 0; i < size; i++) { - appender = (Appender) appenderList.elementAt(i); - appender.doAppend(event); + for(int i = 0; i < size; i++) { + appender = (Appender) appenderList.elementAt(i); + appender.doAppend(event); } - } - + } return size; } + /** Get all attached appenders as an Enumeration. If there are no attached appenders null is returned. - + @return Enumeration An enumeration of attached appenders. */ - public Enumeration getAllAppenders() { - if (appenderList == null) { - return null; + public + Enumeration getAllAppenders() { + if(appenderList == null) { + return null; } else { - return appenderList.elements(); - } + return appenderList.elements(); + } } /** Look for an attached appender named as name.

    Return the appender with that name if in the list. Return null - otherwise. - + otherwise. + */ - public Appender getAppender(String name) { - if ((appenderList == null) || (name == null)) { - return null; + public + Appender getAppender(String name) { + if(appenderList == null || name == null) { + return null; } - int size = appenderList.size(); - Appender appender; - - for (int i = 0; i < size; i++) { - appender = (Appender) appenderList.elementAt(i); - - if (name.equals(appender.getName())) { + int size = appenderList.size(); + Appender appender; + for(int i = 0; i < size; i++) { + appender = (Appender) appenderList.elementAt(i); + if(name.equals(appender.getName())) { return appender; - } } - - return null; + } + return null; } + /** Returns true if the specified appender is in the list of attached appenders, false otherwise. @since 1.2 */ - public boolean isAttached(Appender appender) { - if ((appenderList == null) || (appender == null)) { - return false; + public + boolean isAttached(Appender appender) { + if(appenderList == null || appender == null) { + return false; } - int size = appenderList.size(); - Appender a; - - for (int i = 0; i < size; i++) { - a = (Appender) appenderList.elementAt(i); - - if (a == appender) { + int size = appenderList.size(); + Appender a; + for(int i = 0; i < size; i++) { + a = (Appender) appenderList.elementAt(i); + if(a == appender) { return true; - } } - - return false; + } + return false; } + + /** * Remove and close all previously attached appenders. * */ - public void removeAllAppenders() { - if (appenderList != null) { - int len = appenderList.size(); - - for (int i = 0; i < len; i++) { - Appender a = (Appender) appenderList.elementAt(i); - a.close(); + public + void removeAllAppenders() { + if(appenderList != null) { + int len = appenderList.size(); + for(int i = 0; i < len; i++) { + Appender a = (Appender) appenderList.elementAt(i); + a.close(); } - appenderList.removeAllElements(); - appenderList = null; + appenderList = null; } } + /** Remove the appender passed as parameter form the list of attached appenders. */ - public void removeAppender(Appender appender) { - if ((appender == null) || (appenderList == null)) { - return; + public + void removeAppender(Appender appender) { + if(appender == null || appenderList == null) { + return; } - - appenderList.removeElement(appender); + appenderList.removeElement(appender); } - /** - Remove the appender with the name passed as parameter form the - list of appenders. - */ - public void removeAppender(String name) { - if ((name == null) || (appenderList == null)) { - return; - } + /** + Remove the appender with the name passed as parameter form the + list of appenders. + */ + public + void removeAppender(String name) { + if(name == null || appenderList == null) { + return; + } int size = appenderList.size(); - - for (int i = 0; i < size; i++) { - if (name.equals(((Appender) appenderList.elementAt(i)).getName())) { - appenderList.removeElementAt(i); - - break; + for(int i = 0; i < size; i++) { + if(name.equals(((Appender)appenderList.elementAt(i)).getName())) { + appenderList.removeElementAt(i); + break; } } } + } diff --git a/src/main/java/org/apache/log4j/helpers/BoundedFIFO.java b/src/main/java/org/apache/log4j/helpers/BoundedFIFO.java index 479593d3b8..d53a771e50 100644 --- a/src/main/java/org/apache/log4j/helpers/BoundedFIFO.java +++ b/src/main/java/org/apache/log4j/helpers/BoundedFIFO.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -23,14 +24,10 @@ /** BoundedFIFO serves as the bounded first-in-first-out - buffer previously used by the {@link org.apache.log4j.AsyncAppender}. + buffer heavily used by the {@link org.apache.log4j.AsyncAppender}. @author Ceki Gülcü - @since version 0.9.1 - - @deprecated Since 1.3. - - */ + @since version 0.9.1 */ public class BoundedFIFO { LoggingEvent[] buf; @@ -57,8 +54,9 @@ public class BoundedFIFO { there are no elements in the buffer. */ public LoggingEvent get() { - if(numElements == 0) - return null; + if(numElements == 0) { + return null; + } LoggingEvent r = buf[first]; buf[first] = null; // help garbage collection @@ -94,8 +92,8 @@ int getMaxSize() { } /** - Return true if the buffer is full, that is the - number of elements in the buffer equals the buffer size. */ + Return true if the buffer is full, that is, whether + the number of elements in the buffer equals the buffer size. */ public boolean isFull() { return numElements == maxSize; @@ -126,8 +124,9 @@ int min(int a, int b) { synchronized public void resize(int newSize) { - if(newSize == maxSize) - return; + if(newSize == maxSize) { + return; + } LoggingEvent[] tmp = new LoggingEvent[newSize]; @@ -158,8 +157,9 @@ void resize(int newSize) { this.first=0; this.numElements = len1+len2; this.next = this.numElements; - if(this.next == this.maxSize) // this should never happen, but again, it just might. - this.next = 0; + if(this.next == this.maxSize) { + this.next = 0; +} } diff --git a/src/main/java/org/apache/log4j/helpers/Constants.java b/src/main/java/org/apache/log4j/helpers/Constants.java deleted file mode 100644 index 5fe1f7244d..0000000000 --- a/src/main/java/org/apache/log4j/helpers/Constants.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.helpers; - - -/** - * Constants used internally throughout log4j. - * - * @since 1.3 - */ -public interface Constants { - - /** - * log4j package name string literal. - */ - String LOG4J_PACKAGE_NAME = "org.apache.log4j"; - - /** - * The name of the default repository is "default" (without the quotes). - */ - String DEFAULT_REPOSITORY_NAME = "default"; - - /** - * application string literal. - */ - String APPLICATION_KEY = "application"; - /** - * hostname string literal. - */ - String HOSTNAME_KEY = "hostname"; - /** - * receiver string literal. - */ - String RECEIVER_NAME_KEY = "receiver"; - /** - * log4jid string literal. - */ - String LOG4J_ID_KEY = "log4jid"; - /** - * time stamp pattern string literal. - */ - String TIMESTAMP_RULE_FORMAT = "yyyy/MM/dd HH:mm:ss"; - - /** - * The default property file name for automatic configuration. - */ - String DEFAULT_CONFIGURATION_FILE = "log4j.properties"; - /** - * The default XML configuration file name for automatic configuration. - */ - String DEFAULT_XML_CONFIGURATION_FILE = "log4j.xml"; - /** - * log4j.configuration string literal. - */ - String DEFAULT_CONFIGURATION_KEY = "log4j.configuration"; - /** - * log4j.configuratorClass string literal. - */ - String CONFIGURATOR_CLASS_KEY = "log4j.configuratorClass"; - - /** - * JNDI context name string literal. - */ - String JNDI_CONTEXT_NAME = "java:comp/env/log4j/context-name"; - - /** - * TEMP_LIST_APPENDER string literal. - */ - String TEMP_LIST_APPENDER_NAME = "TEMP_LIST_APPENDER"; - /** - * TEMP_CONSOLE_APPENDER string literal. - */ - String TEMP_CONSOLE_APPENDER_NAME = "TEMP_CONSOLE_APPENDER"; - /** - * Codes URL string literal. - */ - String CODES_HREF = - "http://logging.apache.org/log4j/docs/codes.html"; - - - /** - * ABSOLUTE string literal. - */ - String ABSOLUTE_FORMAT = "ABSOLUTE"; - /** - * SimpleTimePattern for ABSOLUTE. - */ - String ABSOLUTE_TIME_PATTERN = "HH:mm:ss,SSS"; - - - /** - * DATE string literal. - */ - String DATE_AND_TIME_FORMAT = "DATE"; - /** - * SimpleTimePattern for DATE. - */ - String DATE_AND_TIME_PATTERN = "dd MMM yyyy HH:mm:ss,SSS"; - - /** - * ISO8601 string literal. - */ - String ISO8601_FORMAT = "ISO8601"; - /** - * SimpleTimePattern for ISO8601. - */ - String ISO8601_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS"; -} diff --git a/src/main/java/org/apache/log4j/helpers/CountingQuietWriter.java b/src/main/java/org/apache/log4j/helpers/CountingQuietWriter.java index 6d30fcbd0e..55199e47a3 100644 --- a/src/main/java/org/apache/log4j/helpers/CountingQuietWriter.java +++ b/src/main/java/org/apache/log4j/helpers/CountingQuietWriter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -19,6 +20,7 @@ import java.io.Writer; import java.io.IOException; +import org.apache.log4j.spi.ErrorHandler; import org.apache.log4j.spi.ErrorCode; /** @@ -26,20 +28,14 @@ @author Heinz Richter, heinz.richter@frogdot.com @since 0.8.1 - @deprecated */ public class CountingQuietWriter extends QuietWriter { protected long count; - /** - * @deprecated - * @param writer - * @param eh - */ public - CountingQuietWriter(Writer writer, org.apache.log4j.spi.ErrorHandler eh) { + CountingQuietWriter(Writer writer, ErrorHandler eh) { super(writer, eh); } diff --git a/src/main/java/org/apache/log4j/helpers/CyclicBuffer.java b/src/main/java/org/apache/log4j/helpers/CyclicBuffer.java index 216d7f95f7..5c83013106 100644 --- a/src/main/java/org/apache/log4j/helpers/CyclicBuffer.java +++ b/src/main/java/org/apache/log4j/helpers/CyclicBuffer.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -64,13 +65,15 @@ public CyclicBuffer(int maxSize) throws IllegalArgumentException { public void add(LoggingEvent event) { ea[last] = event; - if(++last == maxSize) - last = 0; + if(++last == maxSize) { + last = 0; + } - if(numElems < maxSize) - numElems++; - else if(++first == maxSize) - first = 0; + if(numElems < maxSize) { + numElems++; + } else if(++first == maxSize) { + first = 0; + } } @@ -83,8 +86,9 @@ else if(++first == maxSize) */ public LoggingEvent get(int i) { - if(i < 0 || i >= numElems) - return null; + if(i < 0 || i >= numElems) { + return null; + } return ea[(first + i) % maxSize]; } @@ -105,8 +109,9 @@ LoggingEvent get() { numElems--; r = ea[first]; ea[first] = null; - if(++first == maxSize) - first = 0; + if(++first == maxSize) { + first = 0; + } } return r; } @@ -133,7 +138,9 @@ void resize(int newSize) { "] not allowed."); } if(newSize == numElems) - return; // nothing to do + { + return; // nothing to do + } LoggingEvent[] temp = new LoggingEvent[newSize]; @@ -142,8 +149,9 @@ void resize(int newSize) { for(int i = 0; i < loopLen; i++) { temp[i] = ea[first]; ea[first] = null; - if(++first == numElems) - first = 0; + if(++first == numElems) { + first = 0; + } } ea = temp; first = 0; diff --git a/src/main/java/org/apache/log4j/helpers/DateLayout.java b/src/main/java/org/apache/log4j/helpers/DateLayout.java index c35821570a..383ef38c5a 100644 --- a/src/main/java/org/apache/log4j/helpers/DateLayout.java +++ b/src/main/java/org/apache/log4j/helpers/DateLayout.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -14,194 +15,186 @@ * limitations under the License. */ -// Contributors: Christopher Williams -// Mathias Bogaert package org.apache.log4j.helpers; import org.apache.log4j.Layout; import org.apache.log4j.spi.LoggingEvent; - import java.text.DateFormat; -import java.text.FieldPosition; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; +import java.text.FieldPosition; /** This abstract layout takes care of all the date related options and formatting work. - + @author Ceki Gülcü - @deprecated since 1.3 */ abstract public class DateLayout extends Layout { - /** - String constant designating no time information. Current value of - this constant is NULL. - - */ - public final static String NULL_DATE_FORMAT = "NULL"; - - /** - String constant designating relative time. Current value of - this constant is RELATIVE. - */ - public final static String RELATIVE_TIME_DATE_FORMAT = "RELATIVE"; - - protected FieldPosition pos = new FieldPosition(0); - - /** - @deprecated Options are now handled using the JavaBeans paradigm. - This constant is not longer needed and will be removed in the - near term. - */ - final static public String DATE_FORMAT_OPTION = "DateFormat"; - - /** - @deprecated Options are now handled using the JavaBeans paradigm. - This constant is not longer needed and will be removed in the - near term. - */ - final static public String TIMEZONE_OPTION = "TimeZone"; - - private String timeZoneID; - private String dateFormatOption; - - protected DateFormat dateFormat; - protected Date date = new Date(); - - - /** - * Instantiate a DateLayout object with in the ISO8601 format as the date - * formatter. - * */ - public DateLayout() { - } - - /** - Instantiate a DateLayout object using the local time zone. The - DateFormat used will depend on the dateFormatType. - -

    This constructor just calls the {@link #setDateFormat} method. - */ - public DateLayout(final String dateFormatType) { - this.setDateFormat(dateFormatType); - } - - - /** - @deprecated Use the setter method for the option directly instead - of the generic setOption method. - */ - public - String[] getOptionStrings() { - return new String[] {DATE_FORMAT_OPTION, TIMEZONE_OPTION}; - } - - /** - @deprecated Use the setter method for the option directly instead - of the generic setOption method. - */ - public - void setOption(final String option, final String value) { - if(option.equalsIgnoreCase(DATE_FORMAT_OPTION)) { - dateFormatOption = value.toUpperCase(); - } else if(option.equalsIgnoreCase(TIMEZONE_OPTION)) { - timeZoneID = value; - } - } - - /** - The value of the DateFormat option should be either an - argument to the constructor of {@link SimpleDateFormat} or one of - the srings "NULL", "RELATIVE", "ABSOLUTE", "DATE" or "ISO8601. - */ - public - void setDateFormat(String dateFormat) { - if (dateFormat != null) { - dateFormatOption = dateFormat; - } - setDateFormat(dateFormatOption, TimeZone.getDefault()); - } - - + /** + String constant designating no time information. Current value of + this constant is NULL. + + */ + public final static String NULL_DATE_FORMAT = "NULL"; + + /** + String constant designating relative time. Current value of + this constant is RELATIVE. + */ + public final static String RELATIVE_TIME_DATE_FORMAT = "RELATIVE"; + + protected FieldPosition pos = new FieldPosition(0); + + /** + @deprecated Options are now handled using the JavaBeans paradigm. + This constant is not longer needed and will be removed in the + near term. + */ + final static public String DATE_FORMAT_OPTION = "DateFormat"; + + /** + @deprecated Options are now handled using the JavaBeans paradigm. + This constant is not longer needed and will be removed in the + near term. + */ + final static public String TIMEZONE_OPTION = "TimeZone"; + + private String timeZoneID; + private String dateFormatOption; + + protected DateFormat dateFormat; + protected Date date = new Date(); + + /** + @deprecated Use the setter method for the option directly instead + of the generic setOption method. + */ + public + String[] getOptionStrings() { + return new String[] {DATE_FORMAT_OPTION, TIMEZONE_OPTION}; + } - /** - Returns value of the DateFormat option. - */ - public - String getDateFormat() { - return dateFormatOption; + /** + @deprecated Use the setter method for the option directly instead + of the generic setOption method. + */ + public + void setOption(String option, String value) { + if(option.equalsIgnoreCase(DATE_FORMAT_OPTION)) { + dateFormatOption = value.toUpperCase(); + } else if(option.equalsIgnoreCase(TIMEZONE_OPTION)) { + timeZoneID = value; } - - /** - The TimeZoneID option is a time zone ID string in the format - expected by the {@link TimeZone#getTimeZone} method. - */ - public - void setTimeZone(String timeZone) { - this.timeZoneID = timeZone; + } + + + /** + The value of the DateFormat option should be either an + argument to the constructor of {@link SimpleDateFormat} or one of + the srings "NULL", "RELATIVE", "ABSOLUTE", "DATE" or "ISO8601. + */ + public + void setDateFormat(String dateFormat) { + if (dateFormat != null) { + dateFormatOption = dateFormat; } + setDateFormat(dateFormatOption, TimeZone.getDefault()); + } - /** - Returns value of the TimeZone option. - */ - public - String getTimeZone() { - return timeZoneID; + /** + Returns value of the DateFormat option. + */ + public + String getDateFormat() { + return dateFormatOption; + } + + /** + The TimeZoneID option is a time zone ID string in the format + expected by the {@link TimeZone#getTimeZone} method. + */ + public + void setTimeZone(String timeZone) { + this.timeZoneID = timeZone; + } + + /** + Returns value of the TimeZone option. + */ + public + String getTimeZone() { + return timeZoneID; + } + + public + void activateOptions() { + setDateFormat(dateFormatOption); + if(timeZoneID != null && dateFormat != null) { + dateFormat.setTimeZone(TimeZone.getTimeZone(timeZoneID)); } - - - public void activateOptions() { } - /** - Sets the {@link DateFormat} used to format time and date in the - zone determined by timeZone. - */ - public - void setDateFormat(DateFormat dateFormat, TimeZone timeZone) { - this.dateFormat = dateFormat; - this.dateFormat.setTimeZone(timeZone); + public + void dateFormat(StringBuffer buf, LoggingEvent event) { + if(dateFormat != null) { + date.setTime(event.timeStamp); + dateFormat.format(date, buf, this.pos); + buf.append(' '); } + } - - public void setDateFormat(final String dateFormatStr, final TimeZone timeZone) { - if (dateFormatStr == null) { + /** + Sets the {@link DateFormat} used to format time and date in the + zone determined by timeZone. + */ + public + void setDateFormat(DateFormat dateFormat, TimeZone timeZone) { + this.dateFormat = dateFormat; + this.dateFormat.setTimeZone(timeZone); + } + + /** + Sets the DateFormat used to format date and time in the time zone + determined by timeZone parameter. The {@link DateFormat} used + will depend on the dateFormatType. + +

    The recognized types are {@link #NULL_DATE_FORMAT}, {@link + #RELATIVE_TIME_DATE_FORMAT} {@link + AbsoluteTimeDateFormat#ABS_TIME_DATE_FORMAT}, {@link + AbsoluteTimeDateFormat#DATE_AND_TIME_DATE_FORMAT} and {@link + AbsoluteTimeDateFormat#ISO8601_DATE_FORMAT}. If the + dateFormatType is not one of the above, then the + argument is assumed to be a date pattern for {@link + SimpleDateFormat}. + */ + public + void setDateFormat(String dateFormatType, TimeZone timeZone) { + if(dateFormatType == null) { this.dateFormat = null; return; - } + } - if (!dateFormatStr.equalsIgnoreCase("NULL")) { - if (dateFormatStr.equalsIgnoreCase(RELATIVE_TIME_DATE_FORMAT)) { - this.dateFormat = new RelativeTimeDateFormat(); - } else { - if (dateFormatStr.equalsIgnoreCase(Constants.ABSOLUTE_FORMAT)) { - dateFormat = new SimpleDateFormat(Constants.ABSOLUTE_TIME_PATTERN); - } else if (dateFormatStr.equalsIgnoreCase(Constants.DATE_AND_TIME_FORMAT)) { - dateFormat = new SimpleDateFormat(Constants.DATE_AND_TIME_PATTERN); - } else if (dateFormatStr.equalsIgnoreCase(Constants.ISO8601_FORMAT)) { - dateFormat = new SimpleDateFormat(Constants.ISO8601_PATTERN); - } else { - dateFormat = new SimpleDateFormat(dateFormatStr); - } - if (timeZone != null) { - dateFormat.setTimeZone(timeZone); - } - } + if(dateFormatType.equalsIgnoreCase(NULL_DATE_FORMAT)) { + this.dateFormat = null; + } else if (dateFormatType.equalsIgnoreCase(RELATIVE_TIME_DATE_FORMAT)) { + this.dateFormat = new RelativeTimeDateFormat(); + } else if(dateFormatType.equalsIgnoreCase( + AbsoluteTimeDateFormat.ABS_TIME_DATE_FORMAT)) { + this.dateFormat = new AbsoluteTimeDateFormat(timeZone); + } else if(dateFormatType.equalsIgnoreCase( + AbsoluteTimeDateFormat.DATE_AND_TIME_DATE_FORMAT)) { + this.dateFormat = new DateTimeDateFormat(timeZone); + } else if(dateFormatType.equalsIgnoreCase( + AbsoluteTimeDateFormat.ISO8601_DATE_FORMAT)) { + this.dateFormat = new ISO8601DateFormat(timeZone); + } else { + this.dateFormat = new SimpleDateFormat(dateFormatType); + this.dateFormat.setTimeZone(timeZone); } } - - - public - void dateFormat(StringBuffer buf, LoggingEvent event) { - if(dateFormat != null) { - date.setTime(event.timeStamp); - dateFormat.format(date, buf, this.pos); - buf.append(' '); - } - } } diff --git a/src/main/java/org/apache/log4j/helpers/DateTimeDateFormat.java b/src/main/java/org/apache/log4j/helpers/DateTimeDateFormat.java index 4eda99f4a3..e8759b8603 100644 --- a/src/main/java/org/apache/log4j/helpers/DateTimeDateFormat.java +++ b/src/main/java/org/apache/log4j/helpers/DateTimeDateFormat.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,41 +17,70 @@ package org.apache.log4j.helpers; +import java.util.Calendar; import java.util.TimeZone; import java.util.Date; +import java.text.FieldPosition; +import java.text.ParsePosition; import java.text.DateFormatSymbols; /** - * Formats a {@link Date} in the format "dd MMM yyyy HH:mm:ss,SSS" for example, - * "06 Nov 1994 15:49:37,459". - * - * @author Ceki Gülcü - * @since 0.7.5 - * @deprecated - */ + Formats a {@link Date} in the format "dd MMM yyyy HH:mm:ss,SSS" for example, + "06 Nov 1994 15:49:37,459". + + @author Ceki Gülcü + @since 0.7.5 +*/ public class DateTimeDateFormat extends AbsoluteTimeDateFormat { - /** - * Equivalent format string for SimpleDateFormat. - */ - private final static String PATTERN = "dd MMM yyyy HH:mm:ss,SSS"; - /** Short names for the months. */ - String[] shortMonths = new DateFormatSymbols().getShortMonths(); - - /** - * Create a new instance of DateTimeDateFormat. - */ - public DateTimeDateFormat() { - super(PATTERN); - } + private static final long serialVersionUID = 5547637772208514971L; + + String[] shortMonths; + + public + DateTimeDateFormat() { + super(); + shortMonths = new DateFormatSymbols().getShortMonths(); + } + public + DateTimeDateFormat(TimeZone timeZone) { + this(); + setCalendar(Calendar.getInstance(timeZone)); + } - /** - * Create a new instance of DateTimeDateFormat. - * - * @param timeZone time zone used in conversion, may not be null. - */ - public DateTimeDateFormat(final TimeZone timeZone) { - super(PATTERN, timeZone); + /** + Appends to sbuf the date in the format "dd MMM yyyy + HH:mm:ss,SSS" for example, "06 Nov 1994 08:49:37,459". + + @param sbuf the string buffer to write to + */ + public + StringBuffer format(Date date, StringBuffer sbuf, + FieldPosition fieldPosition) { + + calendar.setTime(date); + + int day = calendar.get(Calendar.DAY_OF_MONTH); + if(day < 10) { + sbuf.append('0'); } + sbuf.append(day); + sbuf.append(' '); + sbuf.append(shortMonths[calendar.get(Calendar.MONTH)]); + sbuf.append(' '); + + int year = calendar.get(Calendar.YEAR); + sbuf.append(year); + sbuf.append(' '); + + return super.format(date, sbuf, fieldPosition); + } + /** + This method does not do anything but return null. + */ + public + Date parse(java.lang.String s, ParsePosition pos) { + return null; + } } diff --git a/src/main/java/org/apache/log4j/helpers/FileWatchdog.java b/src/main/java/org/apache/log4j/helpers/FileWatchdog.java index 0d45212b47..b78a4af16c 100644 --- a/src/main/java/org/apache/log4j/helpers/FileWatchdog.java +++ b/src/main/java/org/apache/log4j/helpers/FileWatchdog.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,47 +16,42 @@ */ // Contributors: Mathias Bogaert + package org.apache.log4j.helpers; import java.io.File; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; - - /** Check every now and then that a certain file has not changed. If it has, then call the {@link #doOnChange} method. - This class has been deprecated and is no longer used by either - PropertyConfigurator or DOMConfigurator. - + @author Ceki Gülcü - @since version 0.9.1 - @deprecated Use org.apache.log4j.watchdog.FileWatchdog instead. -*/ + @since version 0.9.1 */ public abstract class FileWatchdog extends Thread { + /** The default delay between every file modification check, set to 60 seconds. */ - public static final long DEFAULT_DELAY = 60000; + static final public long DEFAULT_DELAY = 60000; /** The name of the file to observe for changes. */ protected String filename; - - private Logger logger = LogManager.getLogger(SyslogWriter.class); /** The delay to observe between every check. By default set {@link #DEFAULT_DELAY}. */ - protected long delay = DEFAULT_DELAY; + protected long delay = DEFAULT_DELAY; + File file; - long lastModif = 0; + long lastModif = 0; boolean warnedAlready = false; boolean interrupted = false; - protected FileWatchdog(String filename) { + protected + FileWatchdog(String filename) { + super("FileWatchdog"); this.filename = filename; file = new File(filename); setDaemon(true); @@ -65,45 +61,49 @@ protected FileWatchdog(String filename) { /** Set the delay to observe between each check of the file changes. */ - public void setDelay(long delay) { + public + void setDelay(long delay) { this.delay = delay; } - protected abstract void doOnChange(); + abstract + protected + void doOnChange(); - protected void checkAndConfigure() { + protected + void checkAndConfigure() { boolean fileExists; try { fileExists = file.exists(); - } catch (SecurityException e) { - logger.warn( - "Was not allowed to read check file existance, file:[" + filename - + "]."); + } catch(SecurityException e) { + LogLog.warn("Was not allowed to read check file existance, file:["+ + filename+"]."); interrupted = true; // there is no point in continuing return; } - if (fileExists) { + if(fileExists) { long l = file.lastModified(); // this can also throw a SecurityException - if (l > lastModif) { // however, if we reached this point this - lastModif = l; // is very unlikely. - doOnChange(); - warnedAlready = false; + if(l > lastModif) { // however, if we reached this point this + lastModif = l; // is very unlikely. + doOnChange(); + warnedAlready = false; } } else { - if (!warnedAlready) { - logger.debug("[" + filename + "] does not exist."); - warnedAlready = true; + if(!warnedAlready) { + LogLog.debug("["+filename+"] does not exist."); + warnedAlready = true; } } } - public void run() { - while (!interrupted) { + public + void run() { + while(!interrupted) { try { - Thread.sleep(delay); - } catch (InterruptedException e) { - // no interruption expected + Thread.sleep(delay); + } catch(InterruptedException e) { + // no interruption expected } checkAndConfigure(); } diff --git a/src/main/java/org/apache/log4j/helpers/FormattingInfo.java b/src/main/java/org/apache/log4j/helpers/FormattingInfo.java index 5f27c3c145..e158243235 100644 --- a/src/main/java/org/apache/log4j/helpers/FormattingInfo.java +++ b/src/main/java/org/apache/log4j/helpers/FormattingInfo.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -24,17 +25,16 @@ @author Jim Cakalic @author Ceki Gülcü - @since 0.8.2 - @deprecated Since 1.3 + @since 0.8.2 */ public class FormattingInfo { int min = -1; - int max = Integer.MAX_VALUE; + int max = 0x7FFFFFFF; boolean leftAlign = false; void reset() { min = -1; - max = Integer.MAX_VALUE; + max = 0x7FFFFFFF; leftAlign = false; } diff --git a/src/main/java/org/apache/log4j/helpers/ISO8601DateFormat.java b/src/main/java/org/apache/log4j/helpers/ISO8601DateFormat.java index cf0411c2d8..9079a2f30a 100644 --- a/src/main/java/org/apache/log4j/helpers/ISO8601DateFormat.java +++ b/src/main/java/org/apache/log4j/helpers/ISO8601DateFormat.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,45 +17,142 @@ package org.apache.log4j.helpers; +import java.util.Calendar; import java.util.TimeZone; +import java.util.Date; +import java.text.FieldPosition; +import java.text.ParsePosition; // Contributors: Arndt Schoenewald /** - * Formats a {@link java.util.Date} in the format "yyyy-MM-dd HH:mm:ss,SSS" for example - * "1999-11-27 15:49:37,459". - *

    - *

    Refer to the summary of the - * International Standard Date and Time Notation for more - * information on this format. - * - * @author Ceki Gülcü - * @author Andrew Vajoczki - * @since 0.7.5 - * @deprecated - */ + Formats a {@link Date} in the format "yyyy-MM-dd HH:mm:ss,SSS" for example + "1999-11-27 15:49:37,459". + +

    Refer to the summary of the + International Standard Date and Time Notation for more + information on this format. + + @author Ceki Gülcü + @author Andrew Vajoczki + + @since 0.7.5 +*/ public class ISO8601DateFormat extends AbsoluteTimeDateFormat { - /** - * Equivalent format string for SimpleDateFormat. - */ - private static final String FORMAT = "yyyy-MM-dd HH:mm:ss,SSS"; - - /** - * Create a new instance of ISO8601DateFormat. - */ - public ISO8601DateFormat() { - super(FORMAT); + private static final long serialVersionUID = -759840745298755296L; + + public + ISO8601DateFormat() { + } + + public + ISO8601DateFormat(TimeZone timeZone) { + super(timeZone); + } + + static private long lastTime; + static private char[] lastTimeString = new char[20]; + + /** + Appends a date in the format "YYYY-mm-dd HH:mm:ss,SSS" + to sbuf. For example: "1999-11-27 15:49:37,459". + + @param sbuf the StringBuffer to write to + */ + public + StringBuffer format(Date date, StringBuffer sbuf, + FieldPosition fieldPosition) { + + long now = date.getTime(); + int millis = (int)(now % 1000); + + if ((now - millis) != lastTime || lastTimeString[0] == 0) { + // We reach this point at most once per second + // across all threads instead of each time format() + // is called. This saves considerable CPU time. + + calendar.setTime(date); + + int start = sbuf.length(); + + int year = calendar.get(Calendar.YEAR); + sbuf.append(year); + + String month; + switch(calendar.get(Calendar.MONTH)) { + case Calendar.JANUARY: month = "-01-"; break; + case Calendar.FEBRUARY: month = "-02-"; break; + case Calendar.MARCH: month = "-03-"; break; + case Calendar.APRIL: month = "-04-"; break; + case Calendar.MAY: month = "-05-"; break; + case Calendar.JUNE: month = "-06-"; break; + case Calendar.JULY: month = "-07-"; break; + case Calendar.AUGUST: month = "-08-"; break; + case Calendar.SEPTEMBER: month = "-09-"; break; + case Calendar.OCTOBER: month = "-10-"; break; + case Calendar.NOVEMBER: month = "-11-"; break; + case Calendar.DECEMBER: month = "-12-"; break; + default: month = "-NA-"; break; + } + sbuf.append(month); + + int day = calendar.get(Calendar.DAY_OF_MONTH); + if(day < 10) { + sbuf.append('0'); + } + sbuf.append(day); + + sbuf.append(' '); + + int hour = calendar.get(Calendar.HOUR_OF_DAY); + if(hour < 10) { + sbuf.append('0'); + } + sbuf.append(hour); + sbuf.append(':'); + + int mins = calendar.get(Calendar.MINUTE); + if(mins < 10) { + sbuf.append('0'); + } + sbuf.append(mins); + sbuf.append(':'); + + int secs = calendar.get(Calendar.SECOND); + if(secs < 10) { + sbuf.append('0'); + } + sbuf.append(secs); + + sbuf.append(','); + + // store the time string for next time to avoid recomputation + sbuf.getChars(start, sbuf.length(), lastTimeString, 0); + lastTime = now - millis; + } + else { + sbuf.append(lastTimeString); } - /** - * Create a new instance of ISO8601DateFormat. - * - * @param timeZone time zone used in conversion, may not be null. - */ - public ISO8601DateFormat(final TimeZone timeZone) { - super(FORMAT, timeZone); + + if (millis < 100) { + sbuf.append('0'); + } + if (millis < 10) { + sbuf.append('0'); } + sbuf.append(millis); + return sbuf; + } + + /** + This method does not do anything but return null. + */ + public + Date parse(java.lang.String s, ParsePosition pos) { + return null; + } } diff --git a/src/main/java/org/apache/log4j/helpers/IntializationUtil.java b/src/main/java/org/apache/log4j/helpers/IntializationUtil.java deleted file mode 100644 index 497a0b8824..0000000000 --- a/src/main/java/org/apache/log4j/helpers/IntializationUtil.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.helpers; - -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggerRepositoryEx; - -import java.net.MalformedURLException; -import java.net.URL; - - -/** - * This class groups certain internally used methods. - * - * @author Ceki Gulcu - * @since 1.3 - */ -public class IntializationUtil { - - - public static void log4jInternalConfiguration(LoggerRepository repository) { - // This method does not do anoything currently. It might become useful - // when sub-domains are added to log4j. - -// Logger logger = repository.getLogger("LOG4J"); -// logger.setAdditivity(false); -// logger.addAppender( -// new ConsoleAppender( -// new PatternLayout("log4j-internal: %r %-22c{2} - %m%n"))); - } - - /** - * Configure repository using configuratonResourceStr - * and configuratorClassNameStr. - * - * If configuratonResourceStr is not a URL it will be searched - * as a resource from the classpath. - * - * @param repository The repository to configre - * @param configuratonResourceStr URL to the configuration resourc - * @param configuratorClassNameStr The name of the class to use as - * the configrator. This parameter can be null. - * */ - public static void initialConfiguration(LoggerRepository repository, - String configuratonResourceStr, - String configuratorClassNameStr) { - - if(configuratonResourceStr == null) { - return; - } - URL url = null; - - try { - url = new URL(configuratonResourceStr); - } catch (MalformedURLException ex) { - // so, resource is not a URL: - // attempt to get the resource from the class loader path - // Please refer to Loader.getResource documentation. - url = Loader.getResource(configuratonResourceStr); - } - - // If we have a non-null url, then delegate the rest of the - // configuration to the OptionConverter.selectAndConfigure - // method. - if (url != null) { - if (repository instanceof LoggerRepositoryEx) { - LogLog.info( - "Using URL [" + url - + "] for automatic log4j configuration of repository named ["+ - ((LoggerRepositoryEx) repository).getName()+"]."); - } else { - LogLog.info( - "Using URL [" + url - + "] for automatic log4j configuration of unnamed repository."); - } - - OptionConverter.selectAndConfigure(url, configuratorClassNameStr, repository); - } - } - - /* - public static void initialConfiguration(LoggerRepository repository) { - String configurationOptionStr = - OptionConverter.getSystemProperty(DEFAULT_CONFIGURATION_KEY, null); - - String configuratorClassName = - OptionConverter.getSystemProperty(CONFIGURATOR_CLASS_KEY, null); - - URL url = null; - - // 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."); - OptionConverter.selectAndConfigure( - url, configuratorClassName, repository); - } else { - LogLog.debug( - "Could not find resources to perform automatic configuration."); - } - } - */ -} diff --git a/src/main/java/org/apache/log4j/helpers/JNDIUtil.java b/src/main/java/org/apache/log4j/helpers/JNDIUtil.java deleted file mode 100644 index a40355fa38..0000000000 --- a/src/main/java/org/apache/log4j/helpers/JNDIUtil.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.helpers; - -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; - - -/** - * - * @author Ceki Gulcu - */ -public class JNDIUtil { - public static Context getInitialContext() throws NamingException { - return new InitialContext(); - } - - public static String lookup(Context ctx, String name) { - if (ctx == null) { - return null; - } - try { - return (String) ctx.lookup(name); - } catch (NamingException e) { - //LogLog.warn("Failed to get "+name); - return null; - } - } -} diff --git a/src/main/java/org/apache/log4j/helpers/Loader.java b/src/main/java/org/apache/log4j/helpers/Loader.java index ab0504a46f..d789f5afda 100644 --- a/src/main/java/org/apache/log4j/helpers/Loader.java +++ b/src/main/java/org/apache/log4j/helpers/Loader.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,43 +18,43 @@ package org.apache.log4j.helpers; import java.net.URL; - +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; +import java.io.InterruptedIOException; /** Load resources (or images) from various sources. - + @author Ceki Gülcü */ -public class Loader { - static final String TSTR = - "Caught Exception while in Loader.getResource. This may be innocuous."; - // We conservatively assume that we are running under Java 1.x - private static boolean java1 = true; - private static boolean ignoreTCL = false; +public class Loader { + + static final String TSTR = "Caught Exception while in Loader.getResource. This may be innocuous."; + // We conservatively assume that we are running under Java 1.x + static private boolean java1 = true; + + static private boolean ignoreTCL = false; + static { String prop = OptionConverter.getSystemProperty("java.version", null); - - if (prop != null) { + + if(prop != null) { int i = prop.indexOf('.'); - - if (i != -1) { - if (prop.charAt(i + 1) != '1') { - java1 = false; - } - } + if(i != -1) { + if(prop.charAt(i+1) != '1') { + java1 = false; } - - String ignoreTCLProp = - OptionConverter.getSystemProperty("log4j.ignoreTCL", null); - - if (ignoreTCLProp != null) { - ignoreTCL = OptionConverter.toBoolean(ignoreTCLProp, true); + } } + String ignoreTCLProp = OptionConverter.getSystemProperty("log4j.ignoreTCL", null); + if(ignoreTCLProp != null) { + ignoreTCL = OptionConverter.toBoolean(ignoreTCLProp, true); + } } - + /** * Get a resource by delegating to getResource(String). * @param resource resource name @@ -72,11 +73,10 @@ public static URL getResource(String resource, Class clazz) {

    1. Search for resource using the thread context - class loader under Java2. This step is performed only if the - skipTCL parameter is false.
    2. - -

    3. If the previous step failed, search for resource using - the class loader that loaded this class (Loader).
    4. + class loader under Java2. If that fails, search for + resource using the class loader that loaded this + class (Loader). Under JDK 1.1, only the the class + loader that loaded this class (Loader) is used.

    5. Try one last time with ClassLoader.getSystemResource(resource), that is is @@ -85,70 +85,90 @@ built-in class loader in JDK 1.1.
    */ - public static URL getResource(String resource) { + static public URL getResource(String resource) { ClassLoader classLoader = null; URL url = null; - + try { - classLoader = getTCL(); - - if (classLoader != null) { -// LogLog.debug( -// "Trying to find [" + resource + "] using context classloader " -// + classLoader + "."); - url = classLoader.getResource(resource); - - if (url != null) { - return url; + if(!java1 && !ignoreTCL) { + classLoader = getTCL(); + if(classLoader != null) { + LogLog.debug("Trying to find ["+resource+"] using context classloader " + +classLoader+"."); + url = classLoader.getResource(resource); + if(url != null) { + return url; + } + } + } + + // We could not find resource. Ler us now try with the + // classloader that loaded this class. + classLoader = Loader.class.getClassLoader(); + if(classLoader != null) { + LogLog.debug("Trying to find ["+resource+"] using "+classLoader + +" class loader."); + url = classLoader.getResource(resource); + if(url != null) { + return url; + } + } + } catch(IllegalAccessException t) { + LogLog.warn(TSTR, t); + } catch(InvocationTargetException t) { + if (t.getTargetException() instanceof InterruptedException + || t.getTargetException() instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); } - } - - // We could not find resource. Ler us now try with the - // classloader that loaded this class. - classLoader = Loader.class.getClassLoader(); - - if (classLoader != null) { -// LogLog.debug( -// "Trying to find [" + resource + "] using " + classLoader -// + " class loader."); - url = classLoader.getResource(resource); - - if (url != null) { - return url; - } - } - } catch (Throwable t) { - // LogLog.warn(TSTR, t); + LogLog.warn(TSTR, t); + } catch(Throwable t) { + // + // can't be InterruptedException or InterruptedIOException + // since not declared, must be error or RuntimeError. + LogLog.warn(TSTR, t); } - + // Last ditch attempt: get the resource from the class path. It // may be the case that clazz was loaded by the Extentsion class // loader which the parent of the system class loader. Hence the // code below. -// LogLog.debug( -// "Trying to find [" + resource -// + "] using ClassLoader.getSystemResource()."); - + LogLog.debug("Trying to find ["+resource+ + "] using ClassLoader.getSystemResource()."); return ClassLoader.getSystemResource(resource); - } - + } + /** - Are we running under JDK 1.x? + Are we running under JDK 1.x? */ - public static boolean isJava1() { + public + static + boolean isJava1() { return java1; } - + /** * Get the Thread Context Loader which is a JDK 1.2 feature. If we * are running under JDK 1.1 or anything else goes wrong the method * returns null. * * */ - private static ClassLoader getTCL() { - return Thread.currentThread().getContextClassLoader(); + private static ClassLoader getTCL() throws IllegalAccessException, + InvocationTargetException { + + // Are we running on a JDK 1.2 or later system? + Method method = null; + try { + method = Thread.class.getMethod("getContextClassLoader", null); + } catch (NoSuchMethodException e) { + // We are running on JDK 1.1 + return null; + } + + return (ClassLoader) method.invoke(Thread.currentThread(), null); } + + /** * If running under JDK 1.2 load the specified class using the * Thread contextClassLoader if that @@ -156,20 +176,26 @@ private static ClassLoader getTCL() { * used. * */ - public static Class loadClass(String clazz) throws ClassNotFoundException { + static public Class loadClass (String clazz) throws ClassNotFoundException { // Just call Class.forName(clazz) if we are running under JDK 1.1 // or if we are instructed to ignore the TCL. - if (java1 || ignoreTCL) { + if(java1 || ignoreTCL) { return Class.forName(clazz); } else { try { - return getTCL().loadClass(clazz); - } catch (Throwable e) { - // we reached here because tcl was null or because of a - // security exception, or because clazz could not be loaded... - // In any case we now try one more time - return Class.forName(clazz); + return getTCL().loadClass(clazz); + } + // we reached here because tcl was null or because of a + // security exception, or because clazz could not be loaded... + // In any case we now try one more time + catch(InvocationTargetException e) { + if (e.getTargetException() instanceof InterruptedException + || e.getTargetException() instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + } catch(Throwable t) { } } + return Class.forName(clazz); } } diff --git a/src/main/java/org/apache/log4j/helpers/LogLog.java b/src/main/java/org/apache/log4j/helpers/LogLog.java index 3c83a29e1f..29869edc19 100644 --- a/src/main/java/org/apache/log4j/helpers/LogLog.java +++ b/src/main/java/org/apache/log4j/helpers/LogLog.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,8 +17,8 @@ package org.apache.log4j.helpers; - -/**This class used to output log statements from within the log4j package. +/** + This class used to output log statements from within the log4j package.

    Log4j components cannot make log4j logging calls. However, it is sometimes useful for the user to learn about what log4j is @@ -28,11 +29,12 @@ where as internal error messages are sent to System.err. All internal messages are prepended with the string "log4j: ". - + @since 0.8.2 @author Ceki Gülcü */ public class LogLog { + /** Defining this value makes log4j print log4j-internal debug statements to System.out. @@ -55,26 +57,25 @@ public class LogLog { */ public static final String CONFIG_DEBUG_KEY="log4j.configDebug"; - /** - Defining this value makes log4j print log4j-internal debug - statements to System.out. - -

    The value of this string is log4j.debug. + protected static boolean debugEnabled = false; -

    Note that the search for all option names is case sensitive. */ - public static final String CORE_DEBUG_KEY = "log4j.coreDebug"; - - protected static boolean debugEnabled = false; + /** + In quietMode not even errors generate any output. + */ + private static boolean quietMode = false; private static final String PREFIX = "log4j: "; private static final String ERR_PREFIX = "log4j:ERROR "; - private static final String INFO_PREFIX = "log4j:INFO "; private static final String WARN_PREFIX = "log4j:WARN "; static { - String key = OptionConverter.getSystemProperty(CORE_DEBUG_KEY, null); + String key = OptionConverter.getSystemProperty(DEBUG_KEY, null); - if (key != null) { + if(key == null) { + key = OptionConverter.getSystemProperty(CONFIG_DEBUG_KEY, null); + } + + if(key != null) { debugEnabled = OptionConverter.toBoolean(key, true); } } @@ -82,7 +83,9 @@ public class LogLog { /** Allows to enable/disable log4j internal logging. */ - public static void setInternalDebugging(boolean enabled) { + static + public + void setInternalDebugging(boolean enabled) { debugEnabled = enabled; } @@ -90,84 +93,102 @@ public static void setInternalDebugging(boolean enabled) { This method is used to output log4j internal debug statements. Output goes to System.out. */ - public static void debug(String msg) { - if (debugEnabled) { - System.out.println(PREFIX + msg); + public + static + void debug(String msg) { + if(debugEnabled && !quietMode) { + System.out.println(PREFIX+msg); } } - public static void info(String msg) { - System.out.println(INFO_PREFIX + msg); - } - /** This method is used to output log4j internal debug statements. Output goes to System.out. */ - public static void debug(String msg, Throwable t) { - if (debugEnabled) { - System.out.println(PREFIX + msg); - - if (t != null) { + public + static + void debug(String msg, Throwable t) { + if(debugEnabled && !quietMode) { + System.out.println(PREFIX+msg); + if(t != null) { t.printStackTrace(System.out); - } + } } } + /** - * This method is used to output log4j internal error statements. There is no - * way to disable error statements. Output goes to System.err. - * @deprecated Use {@link org.apache.log4j.Logger} instead. + This method is used to output log4j internal error + statements. There is no way to disable error statements. + Output goes to System.err. */ - public static void error(String msg) { - System.err.println(ERR_PREFIX + msg); - } + public + static + void error(String msg) { + if(quietMode) { + return; + } + System.err.println(ERR_PREFIX+msg); + } /** - * This method is used to output log4j internal error statements. There is no - * way to disable error statements. Output goes to System.err. - * @deprecated Use {@link org.apache.log4j.Logger} instead. - **/ - public static void error(String msg, Throwable t) { - System.err.println(ERR_PREFIX + msg); - - if (t != null) { + This method is used to output log4j internal error + statements. There is no way to disable error statements. + Output goes to System.err. + */ + public + static + void error(String msg, Throwable t) { + if(quietMode) { + return; + } + + System.err.println(ERR_PREFIX+msg); + if(t != null) { t.printStackTrace(); } - } + } /** - * In quite mode no LogLog generates strictly no output, not even - * for errors. - * @param quietMode A true for not - * @deprecated with no replacement + In quite mode no LogLog generates strictly no output, not even + for errors. + + @param quietMode A true for not */ - public static void setQuietMode(boolean quietMode) { - // nothing to do + public + static + void setQuietMode(boolean quietMode) { + LogLog.quietMode = quietMode; } /** - * This method is used to output log4j internal warning statements. There is - * no way to disable warning statements. Output goes to - * System.err. - * - * @deprecated Use {@link org.apache.log4j.Logger} instead. - * */ - public static void warn(String msg) { - System.err.println(WARN_PREFIX + msg); - } + This method is used to output log4j internal warning + statements. There is no way to disable warning statements. + Output goes to System.err. */ + public + static + void warn(String msg) { + if(quietMode) { + return; + } + + System.err.println(WARN_PREFIX+msg); + } /** - * This method is used to output log4j internal warnings. There is no way to - * disable warning statements. Output goes to System.err. - * - * @deprecated Use {@link org.apache.log4j.Logger} instead. - * */ - public static void warn(String msg, Throwable t) { - System.err.println(WARN_PREFIX + msg); - - if (t != null) { + This method is used to output log4j internal warnings. There is + no way to disable warning statements. Output goes to + System.err. */ + public + static + void warn(String msg, Throwable t) { + if(quietMode) { + return; + } + + System.err.println(WARN_PREFIX+msg); + if(t != null) { t.printStackTrace(); } - } + } } diff --git a/src/main/java/org/apache/log4j/helpers/LoggerTraverse.java b/src/main/java/org/apache/log4j/helpers/LoggerTraverse.java deleted file mode 100644 index 66614013d6..0000000000 --- a/src/main/java/org/apache/log4j/helpers/LoggerTraverse.java +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.helpers; - -import org.apache.log4j.Level; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.spi.LoggerRepository; - -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - - -/** - This helper class can be used to extract/traverse logger information - for a given LoggerRepository. It is a work in progress and focus to - date has been functionality, not performance or efficiency. - - The set of loggers can be retrieved in one of two ways: - - 1) getLoggerNames() - A complete list of the loggers - 2) getLoggerPackageNames() - A list of package names, starting at a - given package name pattern. - - If the second retrieval method is used, the caller can iteratively call - the LoggerTraverse to retrieve sub-packages and children. - - This class is dependent on logger names that match Java fully qualified - class names. - - It also provides methods for querying the current level of a given - logger and - - NOTE: This class does not cause any side effects in the LoggerRepository. - It does not inadvertantly create new Loggers in the process of parsing the - package names or accessing information. - - NOTE: This class does not automatically keep track of changes in the given - LoggerRepository. The caller must call the update() method to get the - current set of loggers. - - @author Mark Womack -*/ -public class LoggerTraverse { - /** A map of all the loggers in the LoggerRepository. */ - private Map loggerMap = new TreeMap(); - - /** A reference to the root logger of the LoggerRepository. */ - private Logger rootLogger; - - /** - Empty constructor. */ - public LoggerTraverse() { - } - - /** - @param repository The LoggerRepository to traverse. */ - public LoggerTraverse(LoggerRepository repository) { - update(repository); - } - - /** - Updates the LoggerTraverse to the current information in the given - LoggerRepository. - - @param repository LoggerRepository to use for Logger information. */ - public void update(LoggerRepository repository) { - // clear any old information - loggerMap.clear(); - - // set the root logger - rootLogger = repository.getRootLogger(); - - // enumerate through the current set of loggers - // the key is the logger name, the value is the logger - Enumeration loggerEnum = repository.getCurrentLoggers(); - - while (loggerEnum.hasMoreElements()) { - Logger logger = (Logger) loggerEnum.nextElement(); - loggerMap.put(logger.getName(), logger); - } - } - - /** - Returns the list of all loggers, sorted by name. - - @return List List of the current loggers. */ - public List getLoggerNames() { - List loggerList = new ArrayList(loggerMap.size()); - Iterator loggerIter = loggerMap.keySet().iterator(); - - while (loggerIter.hasNext()) { - loggerList.add((String) loggerIter.next()); - } - - return loggerList; - } - - /** - Using a starting name pattern, returns the next level of package names - that start with that pattern. Returns a list, as there can be more than - one return value. Passing in an empty string for the starting pattern - will return a list of the top level package names. - - For example, if the following logger names were defined: org.apache.log4j - and org.apache.log4j-extensions, then passing in an empty string would - return one item in the list with a value of "org". If the pattern - "org.apache" were passed in, then the list would contain two items, - "log4j" and "log4j-extensions". - - @param startPattern The name pattern to match for Logger name. - @return List List of matching Logger names that start with the pattern. */ - public List getLoggerPackageNames(String startPattern) { - String name = ""; - List packageList = new ArrayList(1); - - // iterate through the loggerMap, checking the name of each logger - // against the starting pattern. If name starts with pattern, then - // add the next part of the package name to the return list. - Iterator loggerIter = loggerMap.keySet().iterator(); - - while (loggerIter.hasNext()) { - String loggerName = (String) loggerIter.next(); - - // does the logger name start with the startPattern - if (loggerName.startsWith(startPattern)) { - loggerName = loggerName.substring(startPattern.length()); - - // is there part of the name left after the start pattern is removed? - if (loggerName.length() > 0) { - // if the left over string starts with '.'. remove it - if (loggerName.startsWith(".")) { - loggerName = loggerName.substring(1); - } else if (startPattern.length() > 0) { - break; - } - - // find the next index of '.' and grab the part of the name before it - int index = loggerName.indexOf('.'); - - if (index != -1) { - //System.out.println("found . at " + index); - loggerName = loggerName.substring(0, index); - } - - // if this is not a name we have previously encountered, - // put it in the return list. - if (!loggerName.equals(name)) { - packageList.add(loggerName); - name = loggerName; - } - } - } - } - - return packageList; - } - - /** - Returns true if the given package name appears to have sub-package. - - @param startPattern The name pattern to match for Logger name. - @return boolean True if there are existing loggers that match. */ - public boolean loggerHasSubPackages(String startPattern) { - int len = startPattern.length(); - - // iterate through logger names and first one that starts with - // pattern and the length is greater, return true. - Iterator loggerIter = loggerMap.keySet().iterator(); - - while (loggerIter.hasNext()) { - String loggerName = (String) loggerIter.next(); - - if (loggerName.startsWith(startPattern) && (loggerName.length() > len)) { - return true; - } - } - - return false; - } - - /** - Returns the level for the root logger. - - @return Level The current Level for the root logger. */ - public Level getLevelForRootLogger() { - return rootLogger.getEffectiveLevel(); - } - - /** - Returns the effective level for the given package name. If no level is - set for the given package, then search back through the package names - until one is found that is set or return the level of the root logger. - - @param packageName The name of the logger to return the level for. - @return Level The level of the logger. */ - public Level getLevelForPackage(String packageName) { - String name = packageName; - Logger logger = (Logger) loggerMap.get(packageName); - - while ((logger == null) && (name != null)) { - int index = name.lastIndexOf('.'); - - if (index != -1) { - name = name.substring(0, index - 1); - logger = (Logger) loggerMap.get(packageName); - } else { - name = null; - } - } - - if (logger != null) { - return logger.getEffectiveLevel(); - } else { - return rootLogger.getEffectiveLevel(); - } - } - - /** - Returns true of the package has had its level set directly or - false if the level is inherited. - - @param packageName The name of the logger to return the level for. - @return boolean True if the level has been explicitly configured. */ - public boolean getLevelIsSetForPackage(String packageName) { - String name = packageName; - Logger logger = (Logger) loggerMap.get(packageName); - - while ((logger == null) && (name != null)) { - int index = name.lastIndexOf('.'); - - if (index != -1) { - name = name.substring(0, index - 1); - logger = (Logger) loggerMap.get(packageName); - } else { - name = null; - } - } - - if (logger != null) { - if (logger == rootLogger) { - return true; - } else { - return (logger.getLevel() != null); - } - } else { - return false; - } - } - - /** - here is an example of using the hierarchical version, iterating - through all the package names, all the loggers. - - @param args Parameters for main execution. */ - public static void main(String[] args) { - // set the root to level warn - Logger.getRootLogger().setLevel(Level.ERROR); - - // create some loggers - Logger.getLogger("org.womacknet.wgntool.Researcher"); - Logger.getLogger("org.womacknet.wgntool.ResearcherList"); - Logger.getLogger("org.womacknet.wgntool").setLevel(Level.WARN); - Logger.getLogger("org.womacknet.util.NameUtil"); - Logger.getLogger("com.widgets_r_us.util.StringUtil").setLevel(Level.DEBUG); - - LoggerTraverse info = new LoggerTraverse(LogManager.getLoggerRepository()); - System.out.println("NOTE: '*' indicates the level has not been " - + "explicitly configured for that logger"); - System.out.println("root - " + info.getLevelForRootLogger()); - iteratePackages("", 1, info); - } - - /** - Starting with a package name, iterate through all subpackages and loggers. - - @param startPackageName The logger name to start iterating from. - @param level The indentation value for display of logger names. - @param info The TraverseInfo instance to iterate. */ - static void iteratePackages( - String startPackageName, int level, LoggerTraverse info) { - List packageInfo = info.getLoggerPackageNames(startPackageName); - Iterator iter = packageInfo.iterator(); - - while (iter.hasNext()) { - String packageName = (String) iter.next(); - - for (int x = 0; x < level; x++) { - System.out.print(" "); - } - - System.out.print(packageName); - - String subpackageName; - - if (startPackageName.length() > 0) { - subpackageName = startPackageName + "." + packageName; - } else { - subpackageName = packageName; - } - - System.out.print(" - " + info.getLevelForPackage(subpackageName)); - System.out.println( - (info.getLevelIsSetForPackage(subpackageName) ? "" : "*")); - - if (info.loggerHasSubPackages(subpackageName)) { - iteratePackages(subpackageName, level + 1, info); - } - } - } -} diff --git a/src/main/java/org/apache/log4j/helpers/MDCKeySetExtractor.java b/src/main/java/org/apache/log4j/helpers/MDCKeySetExtractor.java new file mode 100644 index 0000000000..2d2a53905a --- /dev/null +++ b/src/main/java/org/apache/log4j/helpers/MDCKeySetExtractor.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.helpers; + +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.pattern.LogEvent; + +import java.lang.reflect.Method; +import java.util.Set; +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ObjectInputStream; + + +public final class MDCKeySetExtractor { + private final Method getKeySetMethod; + public static final MDCKeySetExtractor INSTANCE = + new MDCKeySetExtractor(); + + + private MDCKeySetExtractor() { + // + // log4j 1.2.15 and later will have method to get names + // of all keys in MDC + // + Method getMethod = null; + + try { + getMethod = LoggingEvent.class.getMethod( + "getPropertyKeySet", null); + } catch(Exception ex) { + getMethod = null; + } + getKeySetMethod = getMethod; + + } + + public Set getPropertyKeySet(final LoggingEvent event) throws Exception { + // + // MDC keys are not visible prior to log4j 1.2.15 + // + Set keySet = null; + if (getKeySetMethod != null) { + keySet = (Set) getKeySetMethod.invoke(event, null); + } else { + // + // for 1.2.14 and earlier could serialize and + // extract MDC content + ByteArrayOutputStream outBytes = new ByteArrayOutputStream(); + ObjectOutputStream os = new ObjectOutputStream(outBytes); + os.writeObject(event); + os.close(); + + byte[] raw = outBytes.toByteArray(); + // + // bytes 6 and 7 should be the length of the original classname + // should be the same as our substitute class name + final String subClassName = LogEvent.class.getName(); + if (raw[6] == 0 || raw[7] == subClassName.length()) { + // + // manipulate stream to use our class name + // + for (int i = 0; i < subClassName.length(); i++) { + raw[8 + i] = (byte) subClassName.charAt(i); + } + ByteArrayInputStream inBytes = new ByteArrayInputStream(raw); + ObjectInputStream is = new ObjectInputStream(inBytes); + Object cracked = is.readObject(); + if (cracked instanceof LogEvent) { + keySet = ((LogEvent) cracked).getPropertyKeySet(); + } + is.close(); + } + } + return keySet; + } +} diff --git a/src/main/java/org/apache/log4j/helpers/MessageFormatter.java b/src/main/java/org/apache/log4j/helpers/MessageFormatter.java deleted file mode 100644 index ad44e8e0e7..0000000000 --- a/src/main/java/org/apache/log4j/helpers/MessageFormatter.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.helpers; - - -/** - * 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 final class MessageFormatter { - /** - * Private formatter since all methods and members are static. - */ - private MessageFormatter() { - super(); - } - - /** - * Start of replacement block. - */ - private static final char DELIM_START = '{'; - /** - * End of replacement block. - */ - private static final char DELIM_STOP = '}'; - - /** - * Performs single argument substitution for the 'messagePattern' passed as - * parameter. - *

    - * For example, MessageFormatter.format("Hi {}.", "there"); - * will return the string "Hi there.". - *

    - * 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(final String messagePattern, - final 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 - // then we just return messagePattern - if (j == -1 || (j + 1 == len)) { - return messagePattern; - } else { - 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. - *

    - * For example, MessageFormatter.format("Hi {}. My name is {}.", - * "there", "David"); will return the string - * "Hi there. My name is David.". - *

    - * 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(final String messagePattern, - final Object arg1, - final Object arg2) { - int i = 0; - int len = messagePattern.length(); - - StringBuffer sbuf = new StringBuffer(messagePattern.length() + 50); - - for (int l = 0; l < 2; l++) { - int 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)); - if (l == 0) { - sbuf.append(arg1); - } else { - sbuf.append(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/main/java/org/apache/log4j/helpers/NullEnumeration.java b/src/main/java/org/apache/log4j/helpers/NullEnumeration.java index 3daf8c2bf2..0f4310ddfa 100644 --- a/src/main/java/org/apache/log4j/helpers/NullEnumeration.java +++ b/src/main/java/org/apache/log4j/helpers/NullEnumeration.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * diff --git a/src/main/java/org/apache/log4j/helpers/OnlyOnceErrorHandler.java b/src/main/java/org/apache/log4j/helpers/OnlyOnceErrorHandler.java index 51567ca321..950778d011 100644 --- a/src/main/java/org/apache/log4j/helpers/OnlyOnceErrorHandler.java +++ b/src/main/java/org/apache/log4j/helpers/OnlyOnceErrorHandler.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,27 +17,98 @@ package org.apache.log4j.helpers; -import org.apache.log4j.Appender; -import org.apache.log4j.Logger; -import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.spi.ErrorHandler; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.Logger; +import org.apache.log4j.Appender; + +import java.io.InterruptedIOException; /** - ErrorHandler and its implementations are no longer - utilized by Log4j. The ErrorHandler interface and any - implementations of it are only here to provide binary runtime - compatibility with versions previous to 1.3, most specifically - 1.2.xx versions. All methods are NOP's. + + The OnlyOnceErrorHandler implements log4j's default + error handling policy which consists of emitting a message for the + first error in an appender and ignoring all following errors. + +

    The error message is printed on System.err. + +

    This policy aims at protecting an otherwise working application + from being flooded with error messages when logging fails. @author Ceki Gülcü - @since 0.9.0 - @deprecated As of 1.3 - */ -public class OnlyOnceErrorHandler implements org.apache.log4j.spi.ErrorHandler { - public void setLogger(Logger logger) {} - public void activateOptions() {} - public void error(String message, Exception e, int errorCode) {} - public void error(String message, Exception e, int errorCode, LoggingEvent event) {} - public void error(String message) {} - public void setAppender(Appender appender) {} - public void setBackupAppender(Appender appender) {} + @since 0.9.0 */ +public class OnlyOnceErrorHandler implements ErrorHandler { + + + final String WARN_PREFIX = "log4j warning: "; + final String ERROR_PREFIX = "log4j error: "; + + boolean firstTime = true; + + + /** + Does not do anything. + */ + public + void setLogger(Logger logger) { + } + + + /** + No options to activate. + */ + public + void activateOptions() { + } + + + /** + Prints the message and the stack trace of the exception on + System.err. */ + public + void error(String message, Exception e, int errorCode) { + error(message, e, errorCode, null); + } + + /** + Prints the message and the stack trace of the exception on + System.err. + */ + public + void error(String message, Exception e, int errorCode, LoggingEvent event) { + if (e instanceof InterruptedIOException || e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } + if(firstTime) { + LogLog.error(message, e); + firstTime = false; + } + } + + + /** + Print a the error message passed as parameter on + System.err. + */ + public + void error(String message) { + if(firstTime) { + LogLog.error(message); + firstTime = false; + } + } + + /** + Does not do anything. + */ + public + void setAppender(Appender appender) { + } + + /** + Does not do anything. + */ + public + void setBackupAppender(Appender appender) { + } } diff --git a/src/main/java/org/apache/log4j/helpers/Option.java b/src/main/java/org/apache/log4j/helpers/Option.java deleted file mode 100644 index d53fbc556d..0000000000 --- a/src/main/java/org/apache/log4j/helpers/Option.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.helpers; - -/** - * - * - * @author Ceki Gülcü - */ -public class Option { - static final String EMPTY_STR = ""; - - public static boolean isEmpty(String val) { - return ((val == null) || EMPTY_STR.equals(val)); - } -} diff --git a/src/main/java/org/apache/log4j/helpers/OptionConverter.java b/src/main/java/org/apache/log4j/helpers/OptionConverter.java index 499696efc0..e16b195f03 100644 --- a/src/main/java/org/apache/log4j/helpers/OptionConverter.java +++ b/src/main/java/org/apache/log4j/helpers/OptionConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,54 +17,40 @@ package org.apache.log4j.helpers; +import java.io.InputStream; +import java.io.InterruptedIOException; +import java.net.URL; +import java.util.Properties; + import org.apache.log4j.Level; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; -import org.apache.log4j.config.ConfiguratorBase; -import org.apache.log4j.joran.JoranConfigurator; import org.apache.log4j.spi.Configurator; import org.apache.log4j.spi.LoggerRepository; -import java.net.URL; - -import java.util.Properties; - - -// Contributors: Avy Sharell -// Matthieu Verbert -// Colin Sampaleanu - -// Contributors: Avy Sharell -// Matthieu Verbert +// Contributors: Avy Sharell (sharell@online.fr) +// Matthieu Verbert (mve@zurich.ibm.com) // Colin Sampaleanu /** - * A convenience class to convert property values to specific types. - * - * @author Ceki Gülcü - * @author Simon Kitching; - * @author Anders Kristensen - * @author Avy Sharell + A convenience class to convert property values to specific types. + + @author Ceki Gülcü + @author Simon Kitching; + @author Anders Kristensen */ -public class OptionConverter { +public class OptionConverter { + static String DELIM_START = "${"; - static char DELIM_STOP = '}'; + static char DELIM_STOP = '}'; static int DELIM_START_LEN = 2; - static int DELIM_STOP_LEN = 1; - - // TODO: this method should be removed if OptionConverter becomes a static - static Logger getLogger() { - return LogManager.getLogger(OptionConverter.class); - } + static int DELIM_STOP_LEN = 1; - // TODO: this method should be removed if OptionConverter becomes totally static - public static void setLoggerRepository(LoggerRepository lr) { - - } + /** OptionConverter is a static class. */ + private OptionConverter() {} - - public static String[] concatanateArrays(String[] l, String[] r) { + public + static + String[] concatanateArrays(String[] l, String[] r) { int len = l.length + r.length; String[] a = new String[len]; @@ -73,44 +60,42 @@ public static String[] concatanateArrays(String[] l, String[] r) { return a; } - public static String convertSpecialChars(String s) { + public + static + String convertSpecialChars(String s) { char c; int len = s.length(); StringBuffer sbuf = new StringBuffer(len); int i = 0; - - while (i < len) { + while(i < len) { c = s.charAt(i++); - if (c == '\\') { - c = s.charAt(i++); - - if (c == 'n') { - c = '\n'; - } else if (c == 'r') { - c = '\r'; - } else if (c == 't') { - c = '\t'; - } else if (c == 'f') { - c = '\f'; - } else if (c == '\b') { - c = '\b'; - } else if (c == '\"') { - c = '\"'; - } else if (c == '\'') { - c = '\''; - } else if (c == '\\') { - c = '\\'; - } + c = s.charAt(i++); + if(c == 'n') { + c = '\n'; + } else if(c == 'r') { + c = '\r'; + } else if(c == 't') { + c = '\t'; + } else if(c == 'f') { + c = '\f'; + } else if(c == '\b') { + c = '\b'; + } else if(c == '\"') { + c = '\"'; + } else if(c == '\'') { + c = '\''; + } else if(c == '\\') { + c = '\\'; + } } - sbuf.append(c); } - return sbuf.toString(); } + /** Very similar to System.getProperty except that the {@link SecurityException} is hidden. @@ -121,27 +106,32 @@ public static String convertSpecialChars(String s) { value if there is no property with that key. @since 1.1 */ - public static String getSystemProperty(String key, String def) { + public + static + String getSystemProperty(String key, String def) { try { return System.getProperty(key, def); - } catch (Throwable e) { // MS-Java throws com.ms.security.SecurityExceptionEx + } catch(Throwable e) { // MS-Java throws com.ms.security.SecurityExceptionEx + LogLog.debug("Was not allowed to read system property \""+key+"\"."); return def; } } - public static Object instantiateByKey( - Properties props, String key, Class superClass, Object defaultValue) { - // Get the value of the property in string form - String className = findAndSubst(key, props); - if (className == null) { - getLogger().error("Could not find value for key {}", key); + public + static + Object instantiateByKey(Properties props, String key, Class superClass, + Object defaultValue) { + // Get the value of the property in string form + String className = findAndSubst(key, props); + if(className == null) { + LogLog.error("Could not find value for key " + key); return defaultValue; } - // Trim className to avoid trailing spaces that cause problems. - return instantiateByClassName(className.trim(), superClass, defaultValue); + return OptionConverter.instantiateByClassName(className.trim(), superClass, + defaultValue); } /** @@ -151,35 +141,35 @@ public static Object instantiateByKey( returned.

    Case of value is unimportant. */ - public static boolean toBoolean(String value, boolean dEfault) { - if (value == null) { - return dEfault; + public + static + boolean toBoolean(String value, boolean dEfault) { + if(value == null) { + return dEfault; } - String trimmedVal = value.trim(); - - if ("true".equalsIgnoreCase(trimmedVal)) { - return true; + if("true".equalsIgnoreCase(trimmedVal)) { + return true; } - - if ("false".equalsIgnoreCase(trimmedVal)) { - return false; + if("false".equalsIgnoreCase(trimmedVal)) { + return false; } - return dEfault; } - public static int toInt(String value, int dEfault) { - if (value != null) { + public + static + int toInt(String value, int dEfault) { + if(value != null) { String s = value.trim(); - try { - return Integer.valueOf(s).intValue(); - } catch (NumberFormatException e) { - getLogger().error("[{}] is not in proper int form.", s); + return Integer.valueOf(s).intValue(); + } + catch (NumberFormatException e) { + LogLog.error("[" + s + "] is not in proper int form."); + e.printStackTrace(); } } - return dEfault; } @@ -203,102 +193,111 @@ class is used to process the level value. significant for the class name part, if present. @since 1.1 */ - public static Level toLevel(String value, Level defaultValue) { - if (value == null) { - return defaultValue; + public + static + Level toLevel(String value, Level defaultValue) { + if(value == null) { + return defaultValue; } - + value = value.trim(); - int hashIndex = value.indexOf('#'); + int hashIndex = value.indexOf('#'); if (hashIndex == -1) { - if ("NULL".equalsIgnoreCase(value)) { - return null; + if("NULL".equalsIgnoreCase(value)) { + return null; } else { - // no class name specified : use standard Level class - return (Level) Level.toLevel(value, defaultValue); + // no class name specified : use standard Level class + return Level.toLevel(value, defaultValue); } } Level result = defaultValue; - String clazz = value.substring(hashIndex + 1); + String clazz = value.substring(hashIndex+1); String levelName = value.substring(0, hashIndex); // This is degenerate case but you never know. - if ("NULL".equalsIgnoreCase(levelName)) { - return null; + if("NULL".equalsIgnoreCase(levelName)) { + return null; } + LogLog.debug("toLevel" + ":class=[" + clazz + "]" + + ":pri=[" + levelName + "]"); + try { Class customLevel = Loader.loadClass(clazz); // get a ref to the specified class' static method // toLevel(String, org.apache.log4j.Level) - Class[] paramTypes = - new Class[] { String.class, org.apache.log4j.Level.class }; + Class[] paramTypes = new Class[] { String.class, + org.apache.log4j.Level.class + }; java.lang.reflect.Method toLevelMethod = - customLevel.getMethod("toLevel", paramTypes); + customLevel.getMethod("toLevel", paramTypes); // now call the toLevel method, passing level string + default - Object[] params = new Object[] { levelName, defaultValue }; + Object[] params = new Object[] {levelName, defaultValue}; Object o = toLevelMethod.invoke(null, params); result = (Level) o; - } catch (ClassNotFoundException e) { - getLogger().warn("custom level class [" + clazz + "] not found."); - } catch (NoSuchMethodException e) { - getLogger().warn( - "custom level class [" + clazz + "]" + } catch(ClassNotFoundException e) { + LogLog.warn("custom level class [" + clazz + "] not found."); + } catch(NoSuchMethodException e) { + LogLog.warn("custom level class [" + clazz + "]" + " does not have a class function toLevel(String, Level)", e); - } catch (java.lang.reflect.InvocationTargetException e) { - getLogger().warn( - "custom level class [" + clazz + "]" + " could not be instantiated", e); - } catch (ClassCastException e) { - getLogger().warn( - "class [" + clazz + "] is not a subclass of org.apache.log4j.Level", e); - } catch (IllegalAccessException e) { - getLogger().warn( - "class [" + clazz - + "] cannot be instantiated due to access restrictions", e); - } catch (Exception e) { - getLogger().warn( - "class [" + clazz + "], level [" + levelName + "] conversion failed.", - e); + } catch(java.lang.reflect.InvocationTargetException e) { + if (e.getTargetException() instanceof InterruptedException + || e.getTargetException() instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.warn("custom level class [" + clazz + "]" + + " could not be instantiated", e); + } catch(ClassCastException e) { + LogLog.warn("class [" + clazz + + "] is not a subclass of org.apache.log4j.Level", e); + } catch(IllegalAccessException e) { + LogLog.warn("class ["+clazz+ + "] cannot be instantiated due to access restrictions", e); + } catch(RuntimeException e) { + LogLog.warn("class ["+clazz+"], level ["+levelName+ + "] conversion failed.", e); } - return result; - } + } - public static long toFileSize(String value, long dEfault) { - if (value == null) { - return dEfault; + public + static + long toFileSize(String value, long dEfault) { + if(value == null) { + return dEfault; } String s = value.trim().toUpperCase(); long multiplier = 1; int index; - if ((index = s.indexOf("KB")) != -1) { + if((index = s.indexOf("KB")) != -1) { multiplier = 1024; s = s.substring(0, index); - } else if ((index = s.indexOf("MB")) != -1) { - multiplier = 1024 * 1024; + } + else if((index = s.indexOf("MB")) != -1) { + multiplier = 1024*1024; s = s.substring(0, index); - } else if ((index = s.indexOf("GB")) != -1) { - multiplier = 1024 * 1024 * 1024; + } + else if((index = s.indexOf("GB")) != -1) { + multiplier = 1024*1024*1024; s = s.substring(0, index); } - - if (s != null) { + if(s != null) { try { - return Long.valueOf(s).longValue() * multiplier; - } catch (NumberFormatException e) { - getLogger().error("[{}] is not in proper int form.", s); - getLogger().error("[" + value + "] not in expected format.", e); + return Long.valueOf(s).longValue() * multiplier; + } + catch (NumberFormatException e) { + LogLog.error("[" + s + "] is not in proper int form."); + LogLog.error("[" + value + "] not in expected format.", e); } } - return dEfault; } @@ -307,19 +306,19 @@ public static long toFileSize(String value, long dEfault) { props. Then perform variable substitution on the found value. - */ - public static String findAndSubst(String key, Properties props) { + */ + public + static + String findAndSubst(String key, Properties props) { String value = props.getProperty(key); - - if (value == null) { - return null; + if(value == null) { + return null; } try { return substVars(value, props); - } catch (IllegalArgumentException e) { - getLogger().error("Bad option value [" + value + "].", e); - + } catch(IllegalArgumentException e) { + LogLog.error("Bad option value ["+value+"].", e); return value; } } @@ -329,202 +328,172 @@ public static String findAndSubst(String key, Properties props) { className is a subclass of superClass. If that test fails or the object could not be instantiated, then defaultValue is returned. - + @param className The fully qualified class name of the object to instantiate. @param superClass The class to which the new object should belong. @param defaultValue The object to return in case of non-fulfillment */ - public static Object instantiateByClassName( - String className, Class superClass, Object defaultValue) { - if (className != null) { + public + static + Object instantiateByClassName(String className, Class superClass, + Object defaultValue) { + if(className != null) { try { - Class classObj = Loader.loadClass(className); - - if (!superClass.isAssignableFrom(classObj)) { - getLogger().error( - "A \"" + className + "\" object is not assignable to a \"" - + superClass.getName() + "\" variable."); - getLogger().error( - "The class \"" + superClass.getName() + "\" was loaded by "); - getLogger().error( - "[" + superClass.getClassLoader() + "] whereas object of type "); - getLogger().error( - "\"" + classObj.getName() + "\" was loaded by [" - + classObj.getClassLoader() + "]."); - - return defaultValue; - } - - //System.out.println("About to call classObj.newInstance(), "+classObj.getName()); - - return classObj.newInstance(); - } catch(NoClassDefFoundError ncfe) { - getLogger().error("Could not instantiate object of class [" + className + "].", ncfe); - } catch (Throwable e) { - getLogger().error("Could not instantiate object of class [" + className + "].", e); + Class classObj = Loader.loadClass(className); + if(!superClass.isAssignableFrom(classObj)) { + LogLog.error("A \""+className+"\" object is not assignable to a \""+ + superClass.getName() + "\" variable."); + LogLog.error("The class \""+ superClass.getName()+"\" was loaded by "); + LogLog.error("["+superClass.getClassLoader()+"] whereas object of type "); + LogLog.error("\"" +classObj.getName()+"\" was loaded by [" + +classObj.getClassLoader()+"]."); + return defaultValue; + } + return classObj.newInstance(); + } catch (ClassNotFoundException e) { + LogLog.error("Could not instantiate class [" + className + "].", e); + } catch (IllegalAccessException e) { + LogLog.error("Could not instantiate class [" + className + "].", e); + } catch (InstantiationException e) { + LogLog.error("Could not instantiate class [" + className + "].", e); + } catch (RuntimeException e) { + LogLog.error("Could not instantiate class [" + className + "].", e); } } - return defaultValue; } + /** - * Perform variable substitution in string val from the values of - * keys found the properties passed as parameter or in the system propeties. - * - *

    The variable substitution delimeters are ${ and }. - * - *

    For example, if the properties parameter contains a property "key1" set - * as "value1", then the call

    -   *  String s = OptionConverter.substituteVars("Value of key is ${key1}.");
    - * will set the variable s to "Value of key is value1.". - * - *

    If no value could be found for the specified key, then the - * system properties are searched, if the value could not be found - * there, then substitution defaults to the empty string. - * - *

    For example, if system propeties contains no value for the key - * "inexistentKey", then the call - *

    -   * String s = OptionConverter.subsVars("Value of inexistentKey is [${inexistentKey}]"); 
    - * will set s to "Value of inexistentKey is []". - * - *

    Nevertheless, it is possible to specify a default substitution value - * using the ":-" operator. For example, the call - *

    -   * String s = OptionConverter.subsVars("Value of key is [${key2:-val2}]");
    - * will set s to "Value of key is [val2]" even if the "key2" - * property is unset. - * - *

    An {@link java.lang.IllegalArgumentException} is thrown if - * val contains a start delimeter "${" which is not - * balanced by a stop delimeter "}".

    - * - * @param val The string on which variable substitution is performed. - * @throws IllegalArgumentException if val is malformed. - */ - public static String substVars(String val, Properties props) { - - StringBuffer sbuf = new StringBuffer(); + Perform variable substitution in string val from the + values of keys found in the system propeties. - int i = 0; - int j; - int k; +

    The variable substitution delimeters are ${ and }. - while (true) { - j = val.indexOf(DELIM_START, i); +

    For example, if the System properties contains "key=value", then + the call +

    +     String s = OptionConverter.substituteVars("Value of key is ${key}.");
    +     
    - if (j == -1) { - // no more variables - if (i == 0) { // this is a simple string + will set the variable s to "Value of key is value.". - return val; - } else { // add the tail string which contails no variables and return the result. - sbuf.append(val.substring(i, val.length())); +

    If no value could be found for the specified key, then the + props parameter is searched, if the value could not + be found there, then substitution defaults to the empty string. - return sbuf.toString(); - } +

    For example, if system propeties contains no value for the key + "inexistentKey", then the call + +

    +     String s = OptionConverter.subsVars("Value of inexistentKey is [${inexistentKey}]");
    +     
    + will set s to "Value of inexistentKey is []" + +

    An {@link java.lang.IllegalArgumentException} is thrown if + val contains a start delimeter "${" which is not + balanced by a stop delimeter "}".

    + +

    Author Avy Sharell

    + + @param val The string on which variable substitution is performed. + @throws IllegalArgumentException if val is malformed. + + */ + public static + String substVars(String val, Properties props) throws + IllegalArgumentException { + + StringBuffer sbuf = new StringBuffer(); + + int i = 0; + int j, k; + + while(true) { + j=val.indexOf(DELIM_START, i); + if(j == -1) { + // no more variables + if(i==0) { // this is a simple string + return val; + } else { // add the tail string which contails no variables and return the result. + sbuf.append(val.substring(i, val.length())); + return sbuf.toString(); + } } else { - sbuf.append(val.substring(i, j)); - k = val.indexOf(DELIM_STOP, j); - - if (k == -1) { - throw new IllegalArgumentException( - '"' + val + "\" has no closing brace. Opening brace at position " - + j + '.'); - } else { - j += DELIM_START_LEN; - - String rawKey = val.substring(j, k); - - // Massage the key to extract a default replacement if there is one - String[] extracted = extractDefaultReplacement(rawKey); - String key = extracted[0]; - String defaultReplacement = extracted[1]; // can be null - - String replacement = null; - - // first try the props passed as parameter - if(props != null) { - replacement = props.getProperty(key); - } - - // then try in System properties - if (replacement == null) { - replacement = getSystemProperty(key, null); - } - - // if replacement is still null, use the defaultReplacement which - // still be null - if(replacement == null) { - replacement = defaultReplacement; - } - - if (replacement != null) { - // Do variable substitution on the replacement string - // such that we can solve "Hello ${x2}" as "Hello p1" - // where the properties are - // x1=p1 + sbuf.append(val.substring(i, j)); + k = val.indexOf(DELIM_STOP, j); + if(k == -1) { + throw new IllegalArgumentException('"'+val+ + "\" has no closing brace. Opening brace at position " + j + + '.'); + } else { + j += DELIM_START_LEN; + String key = val.substring(j, k); + // first try in System properties + String replacement = getSystemProperty(key, null); + // then try props parameter + if(replacement == null && props != null) { + replacement = props.getProperty(key); + } + + if(replacement != null) { + // Do variable substitution on the replacement string + // such that we can solve "Hello ${x2}" as "Hello p1" + // the where the properties are + // x1=p1 // x2=${x1} - String recursiveReplacement = substVars(replacement, props); - sbuf.append(recursiveReplacement); - } - - i = k + DELIM_STOP_LEN; - } + String recursiveReplacement = substVars(replacement, props); + sbuf.append(recursiveReplacement); + } + i = k + DELIM_STOP_LEN; + } } } } - static public String[] extractDefaultReplacement(String key) { - String[] result = new String[2]; - result[0] = key; - int d = key.indexOf(":-"); - if(d != -1) { - result[0] = key.substring(0, d); - result[1] = key.substring(d+2); - } - return result; - } - - /** - * Replaces double backslashes (except the leading doubles in UNC's) - * with single backslashes for compatibility with existing path specifications - * that were working around use of OptionConverter.convertSpecialChars - * in XML configuration files. - * - * @param src source string - * @return source string with double backslashes replaced - * - * @since 1.3 - */ - public static String stripDuplicateBackslashes(final String src) { - int i = src.lastIndexOf('\\'); - if (i > 0) { - StringBuffer buf = new StringBuffer(src); - for(; i > 0; i = src.lastIndexOf('\\', i - 1)) { - // - // if the preceding character is a slash then - // remove the preceding character - // and continue processing with the earlier part of the string - if(src.charAt(i - 1) == '\\') { - buf.deleteCharAt(i); - i--; - if (i == 0) break; - } else { - // - // if there was a single slash then - // the string was not trying to work around - // convertSpecialChars - // - return src; - } - } - return buf.toString(); - } - return src; + /** + * Configure log4j given an {@link InputStream}. + * + *

    + * The InputStream will be interpreted by a new instance of a log4j configurator. + *

    + *

    + * All configurations steps are taken on the hierarchy passed as a parameter. + *

    + * + * @param inputStream + * The configuration input stream. + * @param clazz + * The class name, of the log4j configurator which will parse the inputStream. This must be a + * subclass of {@link Configurator}, or null. If this value is null then a default configurator of + * {@link PropertyConfigurator} is used. + * @param hierarchy + * The {@link org.apache.log4j.Hierarchy} to act on. + * @since 1.2.17 + */ + +static +public +void selectAndConfigure(InputStream inputStream, String clazz, LoggerRepository hierarchy) { +Configurator configurator = null; + +if(clazz != null) { + LogLog.debug("Preferred configurator class: " + clazz); + configurator = (Configurator) instantiateByClassName(clazz, + Configurator.class, + null); + if(configurator == null) { + LogLog.error("Could not instantiate configurator ["+clazz+"]."); + return; } - +} else { + configurator = new PropertyConfigurator(); +} + +configurator.doConfigure(inputStream, hierarchy); +} + + /** Configure log4j given a URL. @@ -542,37 +511,33 @@ public static String stripDuplicateBackslashes(final String src) { configurator of {@link PropertyConfigurator} is used, unless the filename pointed to by url ends in '.xml', in which case {@link org.apache.log4j.xml.DOMConfigurator} is used. - @param repository The {@link LoggerRepository} to act on. + @param hierarchy The {@link org.apache.log4j.Hierarchy} to act on. @since 1.1.4 */ - public static void selectAndConfigure( - URL url, String clazz, LoggerRepository repository) { - Configurator configurator = null; - String filename = url.getFile(); - - if ((clazz == null) && (filename != null) && filename.endsWith(".xml")) { - clazz = JoranConfigurator.class.getName(); - } - if (clazz != null) { - Logger logger = repository.getLogger(OptionConverter.class.getName()); - logger.info("Preferred configurator class: " + clazz); - - configurator = - (Configurator) instantiateByClassName(clazz, Configurator.class, null); - - if (configurator == null) { - logger.error("Could not instantiate configurator [" + clazz + "]."); - - return; - } - } else { - configurator = new PropertyConfigurator(); - } - - configurator.doConfigure(url, repository); - if(configurator instanceof ConfiguratorBase) { - ((ConfiguratorBase)configurator).dumpErrors(); - } + static + public + void selectAndConfigure(URL url, String clazz, LoggerRepository hierarchy) { + Configurator configurator = null; + String filename = url.getFile(); + + if(clazz == null && filename != null && filename.endsWith(".xml")) { + clazz = "org.apache.log4j.xml.DOMConfigurator"; + } + + if(clazz != null) { + LogLog.debug("Preferred configurator class: " + clazz); + configurator = (Configurator) instantiateByClassName(clazz, + Configurator.class, + null); + if(configurator == null) { + LogLog.error("Could not instantiate configurator ["+clazz+"]."); + return; + } + } else { + configurator = new PropertyConfigurator(); + } + + configurator.doConfigure(url, hierarchy); } } diff --git a/src/main/java/org/apache/log4j/helpers/PatternConverter.java b/src/main/java/org/apache/log4j/helpers/PatternConverter.java index e2ffd44627..f18e264ae0 100644 --- a/src/main/java/org/apache/log4j/helpers/PatternConverter.java +++ b/src/main/java/org/apache/log4j/helpers/PatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -31,12 +32,11 @@ @author Ceki Gülcü @since 0.8.2 - @deprecated Since 1.3 */ public abstract class PatternConverter { public PatternConverter next; int min = -1; - int max = Integer.MAX_VALUE; + int max = 0x7FFFFFFF; boolean leftAlign = false; protected @@ -65,16 +65,17 @@ void format(StringBuffer sbuf, LoggingEvent e) { String s = convert(e); if(s == null) { - if(0 < min) - spacePad(sbuf, min); + if(0 < min) { + spacePad(sbuf, min); + } return; } int len = s.length(); - if(len > max) - sbuf.append(s.substring(len-max)); - else if(len < min) { + if(len > max) { + sbuf.append(s.substring(len-max)); + } else if(len < min) { if(leftAlign) { sbuf.append(s); spacePad(sbuf, min-len); @@ -83,9 +84,9 @@ else if(len < min) { spacePad(sbuf, min-len); sbuf.append(s); } + } else { + sbuf.append(s); } - else - sbuf.append(s); } static String[] SPACES = {" ", " ", " ", " ", //1,2,4,8 spaces diff --git a/src/main/java/org/apache/log4j/helpers/PatternParser.java b/src/main/java/org/apache/log4j/helpers/PatternParser.java index 734b4f73b9..0cd997ae35 100644 --- a/src/main/java/org/apache/log4j/helpers/PatternParser.java +++ b/src/main/java/org/apache/log4j/helpers/PatternParser.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,12 +17,13 @@ package org.apache.log4j.helpers; import org.apache.log4j.Layout; -import org.apache.log4j.spi.LocationInfo; import org.apache.log4j.spi.LoggingEvent; - +import org.apache.log4j.spi.LocationInfo; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Map; +import java.util.Arrays; // Contributors: Nelson Minar <(nelson@monkey.org> // Igor E. Poteryaev @@ -39,7 +41,6 @@ @author Anders Kristensen @since 0.8.2 - @deprecated Since 1.3 */ public class PatternParser { @@ -47,7 +48,6 @@ public class PatternParser { private static final int LITERAL_STATE = 0; private static final int CONVERTER_STATE = 1; - private static final int MINUS_STATE = 2; private static final int DOT_STATE = 3; private static final int MIN_STATE = 4; private static final int MAX_STATE = 5; @@ -181,18 +181,18 @@ PatternConverter parse() { if(c >= '0' && c <= '9') { formattingInfo.min = c - '0'; state = MIN_STATE; - } - else - finalizeConverter(c); + } else { + finalizeConverter(c); + } } // switch break; case MIN_STATE: currentLiteral.append(c); - if(c >= '0' && c <= '9') - formattingInfo.min = formattingInfo.min*10 + (c - '0'); - else if(c == '.') - state = DOT_STATE; - else { + if(c >= '0' && c <= '9') { + formattingInfo.min = formattingInfo.min*10 + (c - '0'); + } else if(c == '.') { + state = DOT_STATE; + } else { finalizeConverter(c); } break; @@ -210,9 +210,9 @@ else if(c == '.') break; case MAX_STATE: currentLiteral.append(c); - if(c >= '0' && c <= '9') - formattingInfo.max = formattingInfo.max*10 + (c - '0'); - else { + if(c >= '0' && c <= '9') { + formattingInfo.max = formattingInfo.max*10 + (c - '0'); + } else { finalizeConverter(c); state = LITERAL_STATE; } @@ -248,19 +248,20 @@ void finalizeConverter(char c) { String dateFormatStr = AbsoluteTimeDateFormat.ISO8601_DATE_FORMAT; DateFormat df; String dOpt = extractOption(); - if(dOpt != null) - dateFormatStr = dOpt; + if(dOpt != null) { + dateFormatStr = dOpt; + } if(dateFormatStr.equalsIgnoreCase( - AbsoluteTimeDateFormat.ISO8601_DATE_FORMAT)) - df = new ISO8601DateFormat(); - else if(dateFormatStr.equalsIgnoreCase( - AbsoluteTimeDateFormat.ABS_TIME_DATE_FORMAT)) - df = new AbsoluteTimeDateFormat(); - else if(dateFormatStr.equalsIgnoreCase( - AbsoluteTimeDateFormat.DATE_AND_TIME_DATE_FORMAT)) - df = new DateTimeDateFormat(); - else { + AbsoluteTimeDateFormat.ISO8601_DATE_FORMAT)) { + df = new ISO8601DateFormat(); + } else if(dateFormatStr.equalsIgnoreCase( + AbsoluteTimeDateFormat.ABS_TIME_DATE_FORMAT)) { + df = new AbsoluteTimeDateFormat(); + } else if(dateFormatStr.equalsIgnoreCase( + AbsoluteTimeDateFormat.DATE_AND_TIME_DATE_FORMAT)) { + df = new DateTimeDateFormat(); + } else { try { df = new SimpleDateFormat(dateFormatStr); } @@ -459,17 +460,35 @@ private static class MDCPatternConverter extends PatternConverter { public String convert(LoggingEvent event) { - Object val = event.getMDC(key); - if(val == null) { - return null; + if (key == null) { + StringBuffer buf = new StringBuffer("{"); + Map properties = event.getProperties(); + if (properties.size() > 0) { + Object[] keys = properties.keySet().toArray(); + Arrays.sort(keys); + for (int i = 0; i < keys.length; i++) { + buf.append('{'); + buf.append(keys[i]); + buf.append(','); + buf.append(properties.get(keys[i])); + buf.append('}'); + } + } + buf.append('}'); + return buf.toString(); } else { - return val.toString(); + Object val = event.getMDC(key); + if(val == null) { + return null; + } else { + return val.toString(); + } } } } - private static class LocationPatternConverter extends PatternConverter { + private class LocationPatternConverter extends PatternConverter { int type; LocationPatternConverter(FormattingInfo formattingInfo, int type) { @@ -508,9 +527,9 @@ private static abstract class NamedPatternConverter extends PatternConverter { public String convert(LoggingEvent event) { String n = getFullyQualifiedName(event); - if(precision <= 0) - return n; - else { + if(precision <= 0) { + return n; + } else { int len = n.length(); // We substract 1 from 'len' when assigning to 'end' to avoid out of @@ -519,8 +538,9 @@ String convert(LoggingEvent event) { int end = len -1 ; for(int i = precision; i > 0; i--) { end = n.lastIndexOf('.', end-1); - if(end == -1) - return n; + if(end == -1) { + return n; + } } return n.substring(end+1, len); } diff --git a/src/main/java/org/apache/log4j/helpers/PlatformInfo.java b/src/main/java/org/apache/log4j/helpers/PlatformInfo.java deleted file mode 100644 index 1933bf7704..0000000000 --- a/src/main/java/org/apache/log4j/helpers/PlatformInfo.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.helpers; - -import java.util.Properties; - - -/** - * This class provides information about the runtime platform. - * - * @author Ceki Gulcu - * @since 1.3 - * */ -public class PlatformInfo { - private static final int UNINITIALIZED = -1; - - // Check if we are running in IBM's visual age. - private static int inVisualAge = UNINITIALIZED; - private static int onAS400 = UNINITIALIZED; - private static int hasStackTraceElement = UNINITIALIZED; - - public static boolean isInVisualAge() { - if (inVisualAge == UNINITIALIZED) { - try { - Class dummy = Class.forName("com.ibm.uvm.tools.DebugSupport"); - inVisualAge = 1; - } catch (Throwable e) { - inVisualAge = 0; - } - } - return (inVisualAge == 1); - } - - /** - * Are we running on AS400? - */ - public static boolean isOnAS400() { - if (onAS400 == UNINITIALIZED) { - try { - Properties p = System.getProperties(); - String osname = p.getProperty("os.name"); - if ((osname != null) && (osname.equals("OS/400"))) { - onAS400 = 1; - } else { - onAS400 = 0; - } - } catch (Throwable e) { - // This should not happen, but if it does, assume we are not on - // AS400. - onAS400 = 0; - } - } - return (onAS400 == 1); - } - - public static boolean hasStackTraceElement() { - if (hasStackTraceElement == UNINITIALIZED) { - try { - Class.forName("java.lang.StackTraceElement"); - hasStackTraceElement = 1; - } catch (Throwable e) { - // we are running on a JDK prior to 1.4 - hasStackTraceElement = 0; - } - } - return (hasStackTraceElement == 1); - } - - public static boolean isJDK14OrLater() { - return hasStackTraceElement(); - } -} diff --git a/src/main/java/org/apache/log4j/helpers/QuietWriter.java b/src/main/java/org/apache/log4j/helpers/QuietWriter.java index 66ef7fae02..778f091b67 100644 --- a/src/main/java/org/apache/log4j/helpers/QuietWriter.java +++ b/src/main/java/org/apache/log4j/helpers/QuietWriter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -18,45 +19,37 @@ import java.io.Writer; import java.io.FilterWriter; -import java.io.IOException; +import org.apache.log4j.spi.ErrorHandler; import org.apache.log4j.spi.ErrorCode; /** QuietWriter does not throw exceptions when things go - wrong. Instead, it delegates error handling to its {@link - org.apache.log4j.spi.ErrorHandler}. + wrong. Instead, it delegates error handling to its {@link ErrorHandler}. @author Ceki Gülcü @since 0.7.3 - @deprecated */ public class QuietWriter extends FilterWriter { - /** - * @deprecated - */ - protected org.apache.log4j.spi.ErrorHandler errorHandler; + protected ErrorHandler errorHandler; - /** - * @deprecated - * @param writer - * @param errorHandler - */ public - QuietWriter(Writer writer, org.apache.log4j.spi.ErrorHandler errorHandler) { + QuietWriter(Writer writer, ErrorHandler errorHandler) { super(writer); setErrorHandler(errorHandler); } public void write(String string) { - try { - out.write(string); - } catch(IOException e) { - errorHandler.error("Failed to write ["+string+"].", e, - ErrorCode.WRITE_FAILURE); + if (string != null) { + try { + out.write(string); + } catch(Exception e) { + errorHandler.error("Failed to write ["+string+"].", e, + ErrorCode.WRITE_FAILURE); + } } } @@ -64,7 +57,7 @@ void write(String string) { void flush() { try { out.flush(); - } catch(IOException e) { + } catch(Exception e) { errorHandler.error("Failed to flush writer,", e, ErrorCode.FLUSH_FAILURE); } @@ -72,7 +65,7 @@ void flush() { public - void setErrorHandler(org.apache.log4j.spi.ErrorHandler eh) { + void setErrorHandler(ErrorHandler eh) { if(eh == null) { // This is a programming error on the part of the enclosing appender. throw new IllegalArgumentException("Attempted to set null ErrorHandler."); diff --git a/src/main/java/org/apache/log4j/helpers/ReaderWriterLock.java b/src/main/java/org/apache/log4j/helpers/ReaderWriterLock.java deleted file mode 100644 index 3412774805..0000000000 --- a/src/main/java/org/apache/log4j/helpers/ReaderWriterLock.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.helpers; - -import java.io.PrintWriter; - - -/** - * - * A RederWriterLock allows multiple readers to obtain the lock at the same time - * but allows only one writer at a time. - * - * When both readers and writers wait to obtain the lock, priority is given to - * waiting writers. - * - * This lock is not reentrant. It is possible for a writer in possession of a writer - * lock to fail to obtain a reader lock. The same goes for reader in possession of a - * reader lock. It can fail to obtain a writer lock. - * - * THIS LOCK IS NOT RENTRANT. - * - * It is the developer's responsability to retstrict the use of this lock to small segments - * of code where reentrancy can be avoided. - * - * Note that the RederWriterLock is only useful in cases where a resource: - * - * 1) Has many frequent read operations performed on it - * 2) Only rarely is the resource modified (written) - * 3) Read operations are invoked by many different threads - * - * If any of the above conditions are not met, it is better to avoid this fancy lock. - * - * @author Ceki Gülcü - * - */ -public class ReaderWriterLock { - int readers = 0; - int writers = 0; - int waitingWriters = 0; - PrintWriter printWriter; - - public ReaderWriterLock() { - } - - public ReaderWriterLock(PrintWriter pw) { - printWriter = pw; - } - - public synchronized void getReadLock() { - if (printWriter != null) { - printMessage("Asking for read lock."); - } - - while ((writers > 0) || (waitingWriters > 0)) { - try { - wait(); - } catch (InterruptedException ie) { - } - } - - if (printWriter != null) { - printMessage("Got read lock."); - } - - readers++; - } - - public synchronized void releaseReadLock() { - if (printWriter != null) { - printMessage("About to release read lock."); - } - - readers--; - - if (waitingWriters > 0) { - notifyAll(); - } - } - - public synchronized void getWriteLock() { - if (printWriter != null) { - printMessage("Asking for write lock."); - } - - waitingWriters++; - - while ((readers > 0) || (writers > 0)) { - try { - wait(); - } catch (InterruptedException ie) { - } - } - - if (printWriter != null) { - printMessage("Got write lock."); - } - - waitingWriters--; - writers++; - } - - public synchronized void releaseWriteLock() { - if (printWriter != null) { - printMessage("About to release write lock."); - } - - writers--; - notifyAll(); - } - - void printMessage(String msg) { - //printWriter.print("["); - printWriter.println(Thread.currentThread().getName() + " " + msg); - } -} diff --git a/src/main/java/org/apache/log4j/helpers/RelativeTimeDateFormat.java b/src/main/java/org/apache/log4j/helpers/RelativeTimeDateFormat.java index 38b8d190ee..ab81a34cf5 100644 --- a/src/main/java/org/apache/log4j/helpers/RelativeTimeDateFormat.java +++ b/src/main/java/org/apache/log4j/helpers/RelativeTimeDateFormat.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -17,20 +18,22 @@ package org.apache.log4j.helpers; import java.util.Date; -import java.util.TimeZone; import java.text.FieldPosition; import java.text.ParsePosition; import java.text.DateFormat; /** Formats a {@link Date} by printing the number of milliseconds - elapsed since the construction of the format. This is the fastest + elapsed since construction of the format. This is the fastest printing DateFormat in the package. @author Ceki Gülcü + @since 0.7.5 */ public class RelativeTimeDateFormat extends DateFormat { + private static final long serialVersionUID = 7055751607085611984L; + protected final long startTime; @@ -59,14 +62,4 @@ StringBuffer format(Date date, StringBuffer sbuf, Date parse(java.lang.String s, ParsePosition pos) { return null; } - - /** - * Sets the timezone. - * Ignored by this formatter, but intercepted to prevent - * NullPointerException in superclass. - * @param tz TimeZone timezone - */ - public void setTimeZone(final TimeZone tz) { - } - } diff --git a/src/main/java/org/apache/log4j/helpers/SyslogQuietWriter.java b/src/main/java/org/apache/log4j/helpers/SyslogQuietWriter.java index 817cbc3465..62e933e40d 100644 --- a/src/main/java/org/apache/log4j/helpers/SyslogQuietWriter.java +++ b/src/main/java/org/apache/log4j/helpers/SyslogQuietWriter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -19,27 +20,21 @@ import java.io.Writer; +import org.apache.log4j.spi.ErrorHandler; /** SyslogQuietWriter extends QuietWriter by prepending the syslog level code before each printed String. @since 0.7.3 - @deprecated */ public class SyslogQuietWriter extends QuietWriter { int syslogFacility; int level; - /** - * @deprecated - * @param writer - * @param syslogFacility - * @param eh - */ public - SyslogQuietWriter(Writer writer, int syslogFacility, org.apache.log4j.spi.ErrorHandler eh) { + SyslogQuietWriter(Writer writer, int syslogFacility, ErrorHandler eh) { super(writer, eh); this.syslogFacility = syslogFacility; } diff --git a/src/main/java/org/apache/log4j/helpers/SyslogWriter.java b/src/main/java/org/apache/log4j/helpers/SyslogWriter.java index bfbbcb8a6e..d6ce4bf6de 100644 --- a/src/main/java/org/apache/log4j/helpers/SyslogWriter.java +++ b/src/main/java/org/apache/log4j/helpers/SyslogWriter.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,21 +17,17 @@ package org.apache.log4j.helpers; -import java.io.IOException; -import java.io.Writer; -import java.net.DatagramPacket; +import java.io.Writer; import java.net.DatagramSocket; import java.net.InetAddress; -import java.net.SocketException; +import java.net.DatagramPacket; import java.net.UnknownHostException; - -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import java.net.SocketException; +import java.io.IOException; import java.net.URL; import java.net.MalformedURLException; - /** SyslogWriter is a wrapper around the java.net.DatagramSocket class so that it behaves like a java.io.Writer. @@ -38,14 +35,18 @@ @since 0.7.3 */ public class SyslogWriter extends Writer { - private static final int SYSLOG_PORT = 514; + + final int SYSLOG_PORT = 514; + /** + * Host string from last constructed SyslogWriter. + * @deprecated + */ + static String syslogHost; + private InetAddress address; private final int port; private DatagramSocket ds; - private Logger logger = LogManager.getLogger(SyslogWriter.class); - private StringBuffer buf = new StringBuffer(); - /** * Constructs a new instance of SyslogWriter. * @param syslogHost host name, may not be null. A port @@ -54,7 +55,9 @@ public class SyslogWriter extends Writer { * address, enclose the IPv6 address in square brackets before appending * the colon and decimal port number. */ - public SyslogWriter(final String syslogHost) { + public + SyslogWriter(final String syslogHost) { + SyslogWriter.syslogHost = syslogHost; if (syslogHost == null) { throw new NullPointerException("syslogHost"); } @@ -78,7 +81,7 @@ public SyslogWriter(final String syslogHost) { urlPort = url.getPort(); } } catch(MalformedURLException e) { - logger.warn("Malformed URL: will attempt to interpret as InetAddress.", e); + LogLog.error("Malformed URL: will attempt to interpret as InetAddress.", e); } } @@ -87,59 +90,56 @@ public SyslogWriter(final String syslogHost) { } port = urlPort; - try { + try { this.address = InetAddress.getByName(host); - } catch (UnknownHostException e) { - logger.error( - "Could not find " + host + ". All logging will FAIL.", e); + } + catch (UnknownHostException e) { + LogLog.error("Could not find " + host + + ". All logging will FAIL.", e); } try { this.ds = new DatagramSocket(); - } catch (SocketException e) { + } + catch (SocketException e) { e.printStackTrace(); - logger.error( - "Could not instantiate DatagramSocket to " + host - + ". All logging will FAIL.", e); + LogLog.error("Could not instantiate DatagramSocket to " + host + + ". All logging will FAIL.", e); } + } - public void write(char[] charArray, int offset, int len) throws IOException { - buf.append(charArray, offset, len); - } - public void write(String str) throws IOException { - buf.append(str); + public + void write(char[] buf, int off, int len) throws IOException { + this.write(new String(buf, off, len)); } - - /** - * Sends the pending data. - */ - public void flush() throws IOException { - if (buf.length() == 0) - return; - // logging here can be problematic during shutdown when writing the footer - // logger.debug("Writing out [{}]", buf); - byte[] bytes = buf.toString().getBytes(); - DatagramPacket packet = - new DatagramPacket(bytes, bytes.length, address, port); - - ds.send(packet); - - // clean up for next time - buf.setLength(0); + + public + void write(final String string) throws IOException { + + if(this.ds != null && this.address != null) { + byte[] bytes = string.getBytes(); + // + // syslog packets must be less than 1024 bytes + // + int bytesLength = bytes.length; + if (bytesLength >= 1024) { + bytesLength = 1024; + } + DatagramPacket packet = new DatagramPacket(bytes, bytesLength, + address, port); + ds.send(packet); + } + } - /** - * Closes the datagram socket. - */ + public + void flush() {} + public void close() { - try { - flush(); - } catch (IOException e) { - // should throw it ... can't change method sig. though - } - ds.close(); + if (ds != null) { + ds.close(); + } } - } diff --git a/src/main/java/org/apache/log4j/helpers/ThreadLocalMap.java b/src/main/java/org/apache/log4j/helpers/ThreadLocalMap.java index 0736f0f57c..da60c86ff4 100644 --- a/src/main/java/org/apache/log4j/helpers/ThreadLocalMap.java +++ b/src/main/java/org/apache/log4j/helpers/ThreadLocalMap.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -28,7 +29,9 @@ */ final public class ThreadLocalMap extends InheritableThreadLocal { - public final Object childValue(Object parentValue) { + public + final + Object childValue(Object parentValue) { Hashtable ht = (Hashtable) parentValue; if(ht != null) { return ht.clone(); diff --git a/src/main/java/org/apache/log4j/helpers/Transform.java b/src/main/java/org/apache/log4j/helpers/Transform.java index f865dd1b0e..7626e71fb9 100644 --- a/src/main/java/org/apache/log4j/helpers/Transform.java +++ b/src/main/java/org/apache/log4j/helpers/Transform.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,93 +17,97 @@ package org.apache.log4j.helpers; -import java.io.IOException; -import java.io.Writer; - - /** Utility class for transforming strings. @author Ceki Gülcü - @author Michael A. McAngus + @author Michael A. McAngus */ public class Transform { - private static final String CDATA_START = ""; - private static final String CDATA_PSEUDO_END = "]]>"; - private static final String CDATA_EMBEDED_END = - CDATA_END + CDATA_PSEUDO_END + CDATA_START; - private static final int CDATA_END_LEN = CDATA_END.length(); + + private static final String CDATA_START = ""; + private static final String CDATA_PSEUDO_END = "]]>"; + private static final String CDATA_EMBEDED_END = CDATA_END + CDATA_PSEUDO_END + CDATA_START; + private static final int CDATA_END_LEN = CDATA_END.length(); /** * This method takes a string which may contain HTML tags (ie, - * <b>, <table>, etc) and replaces any '<' and '>' + * <b>, <table>, etc) and replaces any + * '<', '>' , '&' or '"' * characters with respective predefined entity references. * - * @param input The text to be converted. - */ - public static String escapeTags(final String input) { - //Check if the string is null or zero length -- if so, return - //what was sent in. - if ((input == null) - || (input.length() == 0) - || (input.indexOf("<") == -1 && input.indexOf(">") == -1)) { + * @param input The text to be converted. + * @return The input string with the special characters replaced. + * */ + static public String escapeTags(final String input) { + //Check if the string is null, zero length or devoid of special characters + // if so, return what was sent in. + + if(input == null + || input.length() == 0 + || (input.indexOf('"') == -1 && + input.indexOf('&') == -1 && + input.indexOf('<') == -1 && + input.indexOf('>') == -1)) { return input; } - StringBuffer buf = new StringBuffer(input); - for(int i = 0;i < buf.length(); i++) { - char ch = buf.charAt(i); - if (ch == '<') { - buf.replace(i, i + 1, "<"); - } else if (ch == '>') { - buf.replace(i, i + 1, ">"); - } + //Use a StringBuffer in lieu of String concatenation -- it is + //much more efficient this way. + + StringBuffer buf = new StringBuffer(input.length() + 6); + char ch = ' '; + + int len = input.length(); + for(int i=0; i < len; i++) { + ch = input.charAt(i); + if (ch > '>') { + buf.append(ch); + } else if(ch == '<') { + buf.append("<"); + } else if(ch == '>') { + buf.append(">"); + } else if(ch == '&') { + buf.append("&"); + } else if(ch == '"') { + buf.append("""); + } else { + buf.append(ch); + } } return buf.toString(); } - //public static void appendEscapingCDATA(StringBuffer buf, String str) { - // - //} - /** * Ensures that embeded CDEnd strings (]]>) are handled properly * within message, NDC and throwable tag text. * - * @param output Writer. The - * initial CDSutart () of the CDATA + * @param buf StringBuffer holding the XML data to this point. The + * initial CDStart () of the CDATA * section are the responsibility of the calling method. - * - * @param str The String that is inserted into an existing CDATA Section. + * @param str The String that is inserted into an existing CDATA Section within buf. * */ - public static void appendEscapingCDATA(StringBuffer output, String str) { - if (str == null) { - return; - } - - int end = str.indexOf(CDATA_END); - - if (end < 0) { - output.append(str); - - return; - } - - int start = 0; - - while (end > -1) { - output.append(str.substring(start, end)); - output.append(CDATA_EMBEDED_END); - start = end + CDATA_END_LEN; - - if (start < str.length()) { - end = str.indexOf(CDATA_END, start); - } else { - return; + static public void appendEscapingCDATA(final StringBuffer buf, + final String str) { + if (str != null) { + int end = str.indexOf(CDATA_END); + if (end < 0) { + buf.append(str); + } else { + int start = 0; + while (end > -1) { + buf.append(str.substring(start, end)); + buf.append(CDATA_EMBEDED_END); + start = end + CDATA_END_LEN; + if (start < str.length()) { + end = str.indexOf(CDATA_END, start); + } else { + return; + } + } + buf.append(str.substring(start)); + } } - } - - output.append(str.substring(start)); } } diff --git a/src/main/java/org/apache/log4j/helpers/UtilLoggingLevel.java b/src/main/java/org/apache/log4j/helpers/UtilLoggingLevel.java index 7187ee2b71..b15fbca21d 100644 --- a/src/main/java/org/apache/log4j/helpers/UtilLoggingLevel.java +++ b/src/main/java/org/apache/log4j/helpers/UtilLoggingLevel.java @@ -26,7 +26,6 @@ * An extension of the Level class that provides support for java.util.logging * Levels. * - * @since 1.3 * * @author Scott Deboy (sdeboy@apache.org) */ @@ -41,15 +40,14 @@ public class UtilLoggingLevel extends Level { /** * Numerical value for SEVERE. */ - public static final int SEVERE_INT = 17000; + public static final int SEVERE_INT = 22000; /** * Numerical value for WARNING. */ - public static final int WARNING_INT = 16000; - /** - * Numerical value for INFO. - */ - public static final int INFO_INT = 15000; + public static final int WARNING_INT = 21000; + + //INFO level defined in parent as 20000..no need to redefine here + /** * Numerical value for CONFIG. */ @@ -84,6 +82,7 @@ public class UtilLoggingLevel extends Level { /** * INFO. */ + //note: we've aligned the int values of the java.util.logging INFO level with log4j's level public static final UtilLoggingLevel INFO = new UtilLoggingLevel(INFO_INT, "INFO", 5); /** diff --git a/src/main/java/org/apache/log4j/helpers/package.html b/src/main/java/org/apache/log4j/helpers/package.html index 870a8fdd41..ab75bf3784 100644 --- a/src/main/java/org/apache/log4j/helpers/package.html +++ b/src/main/java/org/apache/log4j/helpers/package.html @@ -1,4 +1,21 @@ + diff --git a/src/main/java/org/apache/log4j/jdbc/JDBCAppender.java b/src/main/java/org/apache/log4j/jdbc/JDBCAppender.java index 830bf94727..25369df94d 100644 --- a/src/main/java/org/apache/log4j/jdbc/JDBCAppender.java +++ b/src/main/java/org/apache/log4j/jdbc/JDBCAppender.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -15,10 +16,6 @@ */ package org.apache.log4j.jdbc; -import org.apache.log4j.PatternLayout; -import org.apache.log4j.spi.ErrorCode; -import org.apache.log4j.spi.LoggingEvent; - import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; @@ -26,15 +23,18 @@ import java.util.ArrayList; import java.util.Iterator; +import org.apache.log4j.PatternLayout; +import org.apache.log4j.spi.ErrorCode; +import org.apache.log4j.spi.LoggingEvent; -/** -

    WARNING: This version of JDBCAppender - is very likely to be completely replaced in the future. Moreoever, - it does not log exceptions. +/** The JDBCAppender provides for sending log events to a database. - +

    WARNING: This version of JDBCAppender + is very likely to be completely replaced in the future. Moreoever, + it does not log exceptions. +

    Each append call adds to an ArrayList buffer. When the buffer is filled each log event is placed in a sql statement (configurable) and executed. @@ -73,11 +73,9 @@ @author Kevin Steppe (ksteppe@pacbell.net) - @deprecated use org.apache.log4j.db.DBAppender instead. */ -public class JDBCAppender extends org.apache.log4j.AppenderSkeleton - implements org.apache.log4j.Appender { +public class JDBCAppender extends org.apache.log4j.AppenderSkeleton { /** * URL of the DB for default connection handling @@ -129,6 +127,8 @@ public class JDBCAppender extends org.apache.log4j.AppenderSkeleton * Helper object for clearing out the buffer */ protected ArrayList removes; + + private boolean locationInfo = false; public JDBCAppender() { super(); @@ -136,14 +136,54 @@ public JDBCAppender() { removes = new ArrayList(bufferSize); } + /** + * Gets whether the location of the logging request call + * should be captured. + * + * @since 1.2.16 + * @return the current value of the LocationInfo option. + */ + public boolean getLocationInfo() { + return locationInfo; + } + + /** + * The LocationInfo 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). + *

    + *

    + * Location information extraction is comparatively very slow and should be + * avoided unless performance is not a concern. + *

    + * @since 1.2.16 + * @param flag true if location information should be extracted. + */ + public void setLocationInfo(final boolean flag) { + locationInfo = flag; + } + + /** * Adds the event to the buffer. When full the buffer is flushed. */ public void append(LoggingEvent event) { + event.getNDC(); + event.getThreadName(); + // Get a copy of this thread's MDC. + event.getMDCCopy(); + if (locationInfo) { + event.getLocationInformation(); + } + event.getRenderedMessage(); + event.getThrowableStrRep(); buffer.add(event); - if (buffer.size() >= bufferSize) - flushBuffer(); + if (buffer.size() >= bufferSize) { + flushBuffer(); + } } /** @@ -176,13 +216,12 @@ protected void execute(String sql) throws SQLException { stmt = con.createStatement(); stmt.executeUpdate(sql); - } catch (SQLException e) { - if (stmt != null) - stmt.close(); - throw e; + } finally { + if(stmt != null) { + stmt.close(); + } + closeConnection(con); } - stmt.close(); - closeConnection(con); //System.out.println("Execute: " + sql); } @@ -205,8 +244,9 @@ protected void closeConnection(Connection con) { * until the object is garbage collected. */ protected Connection getConnection() throws SQLException { - if (!DriverManager.getDrivers().hasMoreElements()) - setDriver("sun.jdbc.odbc.JdbcOdbcDriver"); + if (!DriverManager.getDrivers().hasMoreElements()) { + setDriver("sun.jdbc.odbc.JdbcOdbcDriver"); + } if (connection == null) { connection = DriverManager.getConnection(databaseURL, databaseUser, @@ -225,8 +265,9 @@ public void close() flushBuffer(); try { - if (connection != null && !connection.isClosed()) - connection.close(); + if (connection != null && !connection.isClosed()) { + connection.close(); + } } catch (SQLException e) { errorHandler.error("Error closing connection", e, ErrorCode.GENERIC_FAILURE); } @@ -244,15 +285,16 @@ public void flushBuffer() { //Do the actual logging removes.ensureCapacity(buffer.size()); for (Iterator i = buffer.iterator(); i.hasNext();) { + LoggingEvent logEvent = (LoggingEvent)i.next(); try { - LoggingEvent logEvent = (LoggingEvent)i.next(); String sql = getLogStatement(logEvent); execute(sql); - removes.add(logEvent); } catch (SQLException e) { errorHandler.error("Failed to excute sql", e, ErrorCode.FLUSH_FAILURE); + } finally { + removes.add(logEvent); } } @@ -266,7 +308,6 @@ public void flushBuffer() { /** closes the appender before disposal */ public void finalize() { - super.finalize(); close(); } @@ -282,13 +323,13 @@ public boolean requiresLayout() { /** * */ - public void setSql(String s) { - sqlStatement = s; + public void setSql(String sql) { + sqlStatement = sql; if (getLayout() == null) { - this.setLayout(new PatternLayout(s)); + this.setLayout(new PatternLayout(sql)); } else { - ((PatternLayout)getLayout()).setConversionPattern(s); + ((PatternLayout)getLayout()).setConversionPattern(sql); } } diff --git a/src/main/java/org/apache/log4j/jdbc/package.html b/src/main/java/org/apache/log4j/jdbc/package.html new file mode 100644 index 0000000000..e57e3a5d6d --- /dev/null +++ b/src/main/java/org/apache/log4j/jdbc/package.html @@ -0,0 +1,23 @@ + + + + + The JDBCAppender provides for sending log events to a database. + + \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/jmx/AbstractDynamicMBean.java b/src/main/java/org/apache/log4j/jmx/AbstractDynamicMBean.java index 805ea62c0c..d9d010ae52 100644 --- a/src/main/java/org/apache/log4j/jmx/AbstractDynamicMBean.java +++ b/src/main/java/org/apache/log4j/jmx/AbstractDynamicMBean.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,30 +17,49 @@ package org.apache.log4j.jmx; +import java.util.Enumeration; import java.util.Iterator; -import javax.management.DynamicMBean; -import javax.management.AttributeList; +import java.util.Vector; + import javax.management.Attribute; -import javax.management.RuntimeOperationsException; +import javax.management.AttributeList; +import javax.management.DynamicMBean; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.JMException; import javax.management.MBeanRegistration; +import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; +import javax.management.NotCompliantMBeanException; import javax.management.ObjectName; +import javax.management.RuntimeOperationsException; import org.apache.log4j.Logger; +import org.apache.log4j.Appender; public abstract class AbstractDynamicMBean implements DynamicMBean, MBeanRegistration { - private String dClassName = getClass().getName(); - - /** - * Name of the registered MBean. - */ - private ObjectName objectName; - - /** {@link MBeanServer} instance, set when registration done. */ - private MBeanServer server; - + String dClassName; + MBeanServer server; + private final Vector mbeanList = new Vector(); + + /** + * Get MBean name. + * @param appender appender, may not be null. + * @return name. + * @since 1.2.16 + */ + static protected String getAppenderName(final Appender appender){ + String name = appender.getName(); + if (name == null || name.trim().length() == 0) { + // try to get some form of a name, because null is not allowed (exception), and empty string certainly isn't useful in JMX.. + name = appender.toString(); + } + return name; + } + + /** * Enables the to get the values of several attributes of the Dynamic MBean. */ @@ -56,16 +76,19 @@ AttributeList getAttributes(String[] attributeNames) { AttributeList resultList = new AttributeList(); // if attributeNames is empty, return an empty result list - if (attributeNames.length == 0) - return resultList; + if (attributeNames.length == 0) { + return resultList; + } // build the result attribute list for (int i=0 ; i diff --git a/src/main/java/org/apache/log4j/joran/JoranConfigurator.java b/src/main/java/org/apache/log4j/joran/JoranConfigurator.java deleted file mode 100644 index 342e262f2d..0000000000 --- a/src/main/java/org/apache/log4j/joran/JoranConfigurator.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran; - -import org.apache.log4j.Logger; -import org.apache.log4j.joran.action.NestComponentIA; -import org.apache.log4j.config.ConfiguratorBase; -import org.apache.log4j.joran.action.ActionConst; -import org.apache.log4j.joran.action.AppenderAction; -import org.apache.log4j.joran.action.AppenderRefAction; -import org.apache.log4j.joran.action.ConfigurationAction; -import org.apache.log4j.joran.action.ConversionRuleAction; -import org.apache.log4j.joran.action.JndiSubstitutionPropertyAction; -import org.apache.log4j.joran.action.LayoutAction; -import org.apache.log4j.joran.action.LevelAction; -import org.apache.log4j.joran.action.LoggerAction; -import org.apache.log4j.joran.action.LoggerFactoryAction; -import org.apache.log4j.joran.action.NewRuleAction; -import org.apache.log4j.joran.action.ParamAction; -import org.apache.log4j.joran.action.PluginAction; -import org.apache.log4j.joran.action.PriorityAction; -import org.apache.log4j.joran.action.RepositoryPropertyAction; -import org.apache.log4j.joran.action.RootLoggerAction; -import org.apache.log4j.joran.action.SubstitutionPropertyAction; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.joran.spi.Interpreter; -import org.apache.log4j.joran.spi.JoranDocument; -import org.apache.log4j.joran.spi.Pattern; -import org.apache.log4j.joran.spi.RuleStore; -import org.apache.log4j.joran.spi.SimpleRuleStore; -import org.apache.log4j.spi.ErrorItem; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.ConfiguratorEx; - -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - -import java.lang.reflect.Method; -import java.net.URL; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -/** - * - * A JoranConfigurator instance should not be used more than once to - * configure a LoggerRepository. - * - * @author Curt Arnold - * @author Ceki Gülcü - */ -public class JoranConfigurator extends ConfiguratorBase - implements ConfiguratorEx { - private Interpreter joranInterpreter; - private LoggerRepository repository; - - public JoranConfigurator() { - } - - protected interface ParseAction { - void parse(final SAXParser parser, final DefaultHandler handler) throws SAXException, IOException; - } - - final public void doConfigure(final URL url, final LoggerRepository repository) { - ParseAction action = new ParseAction() { - public void parse(final SAXParser parser, final DefaultHandler handler) throws SAXException, IOException { - parser.parse(url.toString(), handler); - } - }; - doConfigure(action, repository); - } - - final public void doConfigure(final String filename, final LoggerRepository repository) { - ParseAction action = new ParseAction() { - public void parse(final SAXParser parser, final DefaultHandler handler) throws SAXException, IOException { - parser.parse(new File(filename), handler); - } - }; - doConfigure(action, repository); - } - - final public void doConfigure(final File file, final LoggerRepository repository) { - ParseAction action = new ParseAction() { - public void parse(final SAXParser parser, final DefaultHandler handler) throws SAXException, IOException { - parser.parse(file, handler); - } - }; - doConfigure(action, repository); - } - - final public void doConfigure(final InputSource source, final LoggerRepository repository) { - ParseAction action = new ParseAction() { - public void parse(final SAXParser parser, final DefaultHandler handler) throws SAXException, IOException { - parser.parse(source, handler); - } - }; - doConfigure(action, repository); - } - - final public void doConfigure(final InputStream stream, final LoggerRepository repository) { - ParseAction action = new ParseAction() { - public void parse(final SAXParser parser, final DefaultHandler handler) throws SAXException, IOException { - parser.parse(stream, handler); - } - }; - doConfigure(action, repository); - } - - private void setXIncludeAware(SAXParserFactory factory) { - try { - Class sig[] = new Class[] { boolean.class }; - Method m = factory.getClass().getMethod("setXIncludeAware", sig); - m.invoke(factory, new Object[] { Boolean.TRUE }); - } catch (Exception e) { - getLogger().debug("setXIncludeAware not supported"); - } - } - - private Logger getLogger() { - return getLogger(repository); - } - - protected void doConfigure(final ParseAction action, final LoggerRepository repository) { - // This line is needed here because there is logging from inside this method. - this.repository = repository; - selfInitialize(this.repository); - - ExecutionContext ec = joranInterpreter.getExecutionContext(); - List errorList = ec.getErrorList(); - - SAXParser saxParser = null; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setValidating(false); - spf.setNamespaceAware(true); - setXIncludeAware(spf); - saxParser = spf.newSAXParser(); - } catch (Exception pce) { - final String errMsg = "Parser configuration error occured"; - getLogger().error(errMsg, pce); - ec.addError(new ErrorItem(errMsg, pce)); - return; - } - - JoranDocument document = new JoranDocument(errorList, repository); - - try { - action.parse(saxParser, document); - } catch(IOException ie) { - final String errMsg = "I/O error occured while parsing xml file"; - getLogger().error(errMsg, ie); - ec.addError(new ErrorItem(errMsg, ie)); - } catch (Exception ex) { - final String errMsg = "Problem parsing XML document. See previously reported errors. Abandoning all further processing."; - getLogger().error(errMsg, ex); - errorList.add( - new ErrorItem(errMsg)); - return; - } - - ec.pushObject(repository); - String errMsg; - try { - attachListAppender(repository); - - document.replay(joranInterpreter); - - getLogger().debug("Finished parsing."); - } catch (SAXException e) { - // all exceptions should have been recorded already. - } finally { - detachListAppender(repository); - } - - - } - - public List getErrorList() { - return getExecutionContext().getErrorList(); - } - - - protected void selfInitialize(LoggerRepository repository) { - RuleStore rs = new SimpleRuleStore(repository); - rs.addRule(new Pattern("configuration"), new ConfigurationAction()); - rs.addRule( - new Pattern("configuration/substitutionProperty"), - new SubstitutionPropertyAction()); - rs.addRule( - new Pattern("configuration/repositoryProperty"), - new RepositoryPropertyAction()); - rs.addRule( - new Pattern("configuration/conversionRule"), - new ConversionRuleAction()); - rs.addRule(new Pattern("configuration/plugin"), new PluginAction()); - rs.addRule(new Pattern("configuration/logger"), new LoggerAction()); - rs.addRule(new Pattern("configuration/categoryFactory"), new LoggerFactoryAction()); - rs.addRule(new Pattern("configuration/loggerFactory"), new LoggerFactoryAction()); - rs.addRule( - new Pattern("configuration/logger/level"), new LevelAction()); - rs.addRule( - new Pattern("configuration/logger/priority"), new PriorityAction()); - rs.addRule( - new Pattern("configuration/root"), new RootLoggerAction()); - rs.addRule( - new Pattern("configuration/root/level"), new LevelAction()); - rs.addRule( - new Pattern("configuration/root/priority"), new PriorityAction()); - rs.addRule( - new Pattern("configuration/logger/appender-ref"), - new AppenderRefAction()); - rs.addRule( - new Pattern("configuration/root/appender-ref"), - new AppenderRefAction()); - rs.addRule( - new Pattern("configuration/appender"), new AppenderAction()); - rs.addRule(new Pattern("configuration/appender/appender-ref"), - new AppenderRefAction()); - rs.addRule( - new Pattern("configuration/appender/layout"), new LayoutAction()); - rs.addRule( - new Pattern("configuration/jndiSubstitutionProperty"), - new JndiSubstitutionPropertyAction()); - rs.addRule( - new Pattern("configuration/newRule"), new NewRuleAction()); - rs.addRule(new Pattern("*/param"), new ParamAction()); - - joranInterpreter = new Interpreter(rs); - joranInterpreter.setLoggerRepository(repository); - - // The following line adds the capability to parse nested components - joranInterpreter.addImplicitAction(new NestComponentIA()); - ExecutionContext ec = joranInterpreter.getExecutionContext(); - - Map omap = ec.getObjectMap(); - omap.put(ActionConst.APPENDER_BAG, new HashMap()); - omap.put(ActionConst.FILTER_CHAIN_BAG, new HashMap()); - } - - public ExecutionContext getExecutionContext() { - return joranInterpreter.getExecutionContext(); - } -} diff --git a/src/main/java/org/apache/log4j/joran/action/Action.java b/src/main/java/org/apache/log4j/joran/action/Action.java deleted file mode 100644 index d008d4fd28..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/Action.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - -import org.apache.log4j.joran.spi.ActionException; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.joran.spi.Interpreter; -import org.apache.log4j.spi.ComponentBase; -import org.xml.sax.Attributes; -import org.xml.sax.Locator; - - -/** - * - * Most of the work for configuring log4j is done by Actions. - * - * Methods of an Action are invoked while an XML file is parsed through. - * - * This class is largely copied from the relevant class in the commons-digester - * project of the Apache Software Foundation. - * - * @author Craig McClanahan - * @author Christopher Lenz - * @author Ceki Gülcü - * - */ -public abstract class Action extends ComponentBase { - public static final String NAME_ATTRIBUTE = "name"; - public static final String VALUE_ATTRIBUTE = "value"; - public static final String FILE_ATTRIBUTE = "file"; - public static final String CLASS_ATTRIBUTE = "class"; - public static final String PATTERN_ATTRIBUTE = "pattern"; - public static final String ACTION_CLASS_ATTRIBUTE = "actionClass"; - - /** - * Called when the parser first encounters an element. - * - * The return value indicates whether child elements should be processed. If - * the returned value is 'false', then child elements are ignored. - */ - public abstract void begin( - ExecutionContext ec, String name, Attributes attributes) throws ActionException ; - - public abstract void end(ExecutionContext ec, String name) throws ActionException; - - public String toString() { - return this.getClass().getName(); - } - - protected int getColumnNumber(ExecutionContext ec) { - Interpreter jp = ec.getJoranInterpreter(); - Locator locator = jp.getLocator(); - if (locator != null) { - return locator.getColumnNumber(); - } - return -1; - } - - protected int getLineNumber(ExecutionContext ec) { - Interpreter jp = ec.getJoranInterpreter(); - Locator locator = jp.getLocator(); - if (locator != null) { - return locator.getLineNumber(); - } - return -1; - } -} diff --git a/src/main/java/org/apache/log4j/joran/action/ActionConst.java b/src/main/java/org/apache/log4j/joran/action/ActionConst.java deleted file mode 100644 index 50e07b5d9f..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/ActionConst.java +++ /dev/null @@ -1,27 +0,0 @@ - -package org.apache.log4j.joran.action; - -/** - * - * This class contains costants used by other Actions. - * - * @author Ceki Gülcü - * - */ -public abstract class ActionConst { - - public static final String APPENDER_TAG = "appender"; - public static final String REF_ATTRIBUTE = "ref"; - public static final String ADDITIVITY_ATTRIBUTE = "additivity"; - public static final String CONVERTER_CLASS_ATTRIBUTE = "converterClass"; - public static final String CONVERSION_WORD_ATTRIBUTE = "conversionWord"; - public static final String PATTERN_ATTRIBUTE = "pattern"; - public static final String ACTION_CLASS_ATTRIBUTE = "actionClass"; - - static final String INHERITED = "INHERITED"; - static final String NULL = "NULL"; - static final Class[] ONE_STRING_PARAM = new Class[] { String.class }; - - public static final String APPENDER_BAG = "APPENDER_BAG"; - public static final String FILTER_CHAIN_BAG = "FILTER_CHAIN_BAG"; -} diff --git a/src/main/java/org/apache/log4j/joran/action/AppenderAction.java b/src/main/java/org/apache/log4j/joran/action/AppenderAction.java deleted file mode 100644 index ca8fc7f37f..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/AppenderAction.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - - -import org.apache.log4j.Appender; -import org.apache.log4j.helpers.Option; -import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.joran.spi.ActionException; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.spi.ErrorItem; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.OptionHandler; - -import org.xml.sax.Attributes; - -import java.util.HashMap; - - -public class AppenderAction extends Action { - Appender appender; - private boolean inError = false; - - /** - * Instantiates an appender of the given class and sets its name. - * - * The appender thus generated is placed in the ExecutionContext appender bag. - */ - public void begin( - ExecutionContext ec, String localName, Attributes attributes) throws ActionException { - String className = attributes.getValue(CLASS_ATTRIBUTE); - - // We are just beginning, reset variables - appender = null; - inError = false; - - try { - getLogger().debug("About to instantiate appender of type [{}]", className); - - appender = (Appender) OptionConverter.instantiateByClassName( - className, org.apache.log4j.Appender.class, null); - - LoggerRepository repo = (LoggerRepository) ec.getObjectStack().get(0); - appender.setLoggerRepository(repo); - - String appenderName = attributes.getValue(NAME_ATTRIBUTE); - - if (Option.isEmpty(appenderName)) { - getLogger().warn( - "No appender name given for appender of type " + className + "]."); - } else { - appender.setName(appenderName); - getLogger().debug("Appender named as [" + appenderName + "]"); - } - - // The execution context contains a bag which contains the appenders - // created thus far. - HashMap appenderBag = - (HashMap) ec.getObjectMap().get(ActionConst.APPENDER_BAG); - - // add the appender just created to the appender bag. - appenderBag.put(appenderName, appender); - - getLogger().debug("Pushing appender on to the object stack."); - ec.pushObject(appender); - } catch (Exception oops) { - inError = true; - getLogger().error( - "Could not create an Appender. Reported error follows.", oops); - ec.addError( - new ErrorItem("Could not create appender of type " + className + "].")); - throw new ActionException(ActionException.SKIP_CHILDREN, oops); - } - } - - /** - * Once the children elements are also parsed, now is the time to activate - * the appender options. - */ - public void end(ExecutionContext ec, String name) { - if (inError) { - return; - } - - if (appender instanceof OptionHandler) { - ((OptionHandler) appender).activateOptions(); - } - - Object o = ec.peekObject(); - - if (o != appender) { - getLogger().warn( - "The object at the of the stack is not the appender named [" - + appender.getName() + "] pushed earlier."); - } else { - getLogger().debug( - "Popping appender named [" + appender.getName() - + "] from the object stack"); - ec.popObject(); - } - } - - public void finish(ExecutionContext ec) { - } -} diff --git a/src/main/java/org/apache/log4j/joran/action/AppenderRefAction.java b/src/main/java/org/apache/log4j/joran/action/AppenderRefAction.java deleted file mode 100644 index a752d76945..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/AppenderRefAction.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - - -import org.apache.log4j.Appender; -import org.apache.log4j.Logger; -import org.apache.log4j.helpers.Constants; -import org.apache.log4j.helpers.Option; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.spi.AppenderAttachable; -import org.apache.log4j.spi.ErrorItem; - -import org.xml.sax.Attributes; - -import java.util.HashMap; - - -public class AppenderRefAction extends Action { - - public void begin( - ExecutionContext ec, String tagName, Attributes attributes) { - - Object o = ec.peekObject(); - - if (!(o instanceof AppenderAttachable)) { - String errMsg = - "Could not find an AppenderAttachable at the top of execution stack. Near <" - + tagName + "> line " + getLineNumber(ec); - - getLogger().warn(errMsg); - ec.addError(new ErrorItem(errMsg)); - - return; - } - - AppenderAttachable appenderAttachable = (AppenderAttachable) o; - - String appenderName = attributes.getValue(ActionConst.REF_ATTRIBUTE); - - if (Option.isEmpty(appenderName)) { - // print a meaningful error message and return - String errMsg = "Missing appender ref attribute in tag."; - - getLogger().warn(errMsg); - ec.addError(new ErrorItem(errMsg)); - - return; - } - - HashMap appenderBag = - (HashMap) ec.getObjectMap().get(ActionConst.APPENDER_BAG); - Appender appender = (Appender) appenderBag.get(appenderName); - - if (appender == null) { - String msg = "Could not find an appender named ["+appenderName+ - "]. Did you define it below in the config file?"; - getLogger().warn(msg); - getLogger().warn("See {}#appender_order for more details.", Constants.CODES_HREF); - ec.addError(new ErrorItem(msg)); - - return; - } - - if (appenderAttachable instanceof Logger) { - getLogger().debug( - "Attaching appender named [{}] to logger named [{}].", appenderName, ( - (Logger) appenderAttachable).getName()); - } else { - getLogger().debug( - "Attaching appender named [{}] to {}.", appenderName, appenderAttachable); - } - - appenderAttachable.addAppender(appender); - } - - public void end(ExecutionContext ec, String n) { - } - - public void finish(ExecutionContext ec) { - } -} diff --git a/src/main/java/org/apache/log4j/joran/action/ConfigurationAction.java b/src/main/java/org/apache/log4j/joran/action/ConfigurationAction.java deleted file mode 100644 index e0b220b5a8..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/ConfigurationAction.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - -import java.util.List; - - -import org.apache.log4j.config.ConfiguratorBase; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.spi.LoggerRepository; -import org.xml.sax.Attributes; - - -public class ConfigurationAction extends Action { - static final String INTERNAL_DEBUG_ATTR = "debug"; - static final String RESET_ATTR = "reset"; - boolean attachment = false; - - private boolean trueBoolean(String name, String debugAttrib) { - if (debugAttrib == null || debugAttrib.equals("") - || debugAttrib.equals("false") || debugAttrib.equals("null")) { - getLogger().debug("Ignoring " + name + " attribute."); - return false; - } - return true; - } - - public void begin(ExecutionContext ec, String name, Attributes attributes) { - - // reset is applied before debug - String resetAttrib = attributes.getValue(RESET_ATTR); - boolean reset = trueBoolean(RESET_ATTR, resetAttrib); - if (reset) { - LoggerRepository repository = (LoggerRepository) ec.getObject(0); - repository.resetConfiguration(); - } - - String debugAttrib = attributes.getValue(INTERNAL_DEBUG_ATTR); - if (trueBoolean(INTERNAL_DEBUG_ATTR, debugAttrib)) { - LoggerRepository repository = (LoggerRepository) ec.getObject(0); - ConfiguratorBase.attachTemporaryConsoleAppender(repository); - getLogger().debug("Starting internal logs on console."); - attachment = true; - } - - if (reset) { - getLogger().debug("Reset configuration"); - } - - } - - public void end(ExecutionContext ec, String name) { - if (attachment) { - getLogger().debug("Will stop writing internal logs on console."); - LoggerRepository repository = (LoggerRepository) ec.getObject(0); - List errorList = ec.getErrorList(); - ConfiguratorBase.detachTemporaryConsoleAppender(repository, errorList); - } - } -} diff --git a/src/main/java/org/apache/log4j/joran/action/ConversionRuleAction.java b/src/main/java/org/apache/log4j/joran/action/ConversionRuleAction.java deleted file mode 100644 index a0e2571c8d..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/ConversionRuleAction.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.log4j.PatternLayout; -import org.apache.log4j.helpers.Option; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.spi.ErrorItem; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggerRepositoryEx; - - -import org.xml.sax.Attributes; - - -public class ConversionRuleAction extends Action { - - /** - * Instantiates an layout of the given class and sets its name. - * - */ - public void begin(ExecutionContext ec, String localName, Attributes attributes) { - - String errorMsg; - String conversionWord = - attributes.getValue(ActionConst.CONVERSION_WORD_ATTRIBUTE); - String converterClass = - attributes.getValue(ActionConst.CONVERTER_CLASS_ATTRIBUTE); - - if (Option.isEmpty(conversionWord)) { - errorMsg = "No 'conversionWord' attribute in "; - getLogger().warn(errorMsg); - ec.addError(new ErrorItem(errorMsg)); - - return; - } - - if (Option.isEmpty(converterClass)) { - errorMsg = "No 'converterClass' attribute in "; - getLogger().warn(errorMsg); - ec.addError(new ErrorItem(errorMsg)); - - return; - } - - try { - getLogger().debug( - "About to add conversion rule [{}, {}] to layout", conversionWord, converterClass); - - LoggerRepository repository = (LoggerRepository) ec.getObjectStack().get(0); - - // - // cast may fail with user supplied repository - Map ruleRegistry = (Map) ((LoggerRepositoryEx) repository).getObject(PatternLayout.PATTERN_RULE_REGISTRY); - if(ruleRegistry == null) { - ruleRegistry = new HashMap(); - ((LoggerRepositoryEx) repository).putObject(PatternLayout.PATTERN_RULE_REGISTRY, ruleRegistry); - } - // put the new rule into the rule registry - ruleRegistry.put(conversionWord, converterClass); - - } catch (Exception oops) { - errorMsg = "Could not add conversion rule to PatternLayout."; - getLogger().error(errorMsg, oops); - ec.addError(new ErrorItem(errorMsg)); - } - } - - /** - * Once the children elements are also parsed, now is the time to activate - * the appender options. - */ - public void end(ExecutionContext ec, String n) { - } - - public void finish(ExecutionContext ec) { - } -} diff --git a/src/main/java/org/apache/log4j/joran/action/ImplicitAction.java b/src/main/java/org/apache/log4j/joran/action/ImplicitAction.java deleted file mode 100644 index 2707c152d6..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/ImplicitAction.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.joran.spi.Pattern; - -import org.xml.sax.Attributes; - - -/** - * ImplcitActions are like normal (explicit) actions except that are applied - * by the parser when no other pattern applies. Since there can be many implcit - * actions, each action is asked whether it applies in the given context. The - * first impplcit action to respond postively will be applied. See also the - * {@link #isApplicable} method. - * - * @author Ceki Gülcü - */ -public abstract class ImplicitAction extends Action { - - /** - * Check whether this implicit action is apprioriate in the current context. - * - * - * @param currentPattern This pattern contains the tag name of the current - * element being parsed at the top of the stack. - * @param attributes The attributes of the current element to process. - * @param ec - * @return Whether the implicit action is applicable in the current context - */ - public abstract boolean isApplicable( - Pattern currentPattern, Attributes attributes, ExecutionContext ec); - - -} diff --git a/src/main/java/org/apache/log4j/joran/action/JndiSubstitutionPropertyAction.java b/src/main/java/org/apache/log4j/joran/action/JndiSubstitutionPropertyAction.java deleted file mode 100644 index 2440651f26..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/JndiSubstitutionPropertyAction.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.spi.ErrorItem; - -import org.xml.sax.Attributes; - -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; - - -/** - * This action looks up JNDI properties specified in the configuration - * file and adds them to the Joran ExecutionContext. The - * element in the configuration file should have an attribute called - * "name". This attribute will be the key to the naming context lookup, - * as well as the key to the ExecutionContext properties. If a value - * is found whose name matches the given name, it will be placed - * in the ExecutionContext's properties. - * - * @author Yoav Shapira - */ -public class JndiSubstitutionPropertyAction extends Action { - /** - * The naming context. - */ - private Context namingContext; - - /** - * Returns the naming context for lookups. - * - * @return The context (may be null) - */ - protected Context getNamingContext() { - return namingContext; - } - - /** - * Creates the naming context. This is an expensive - * operation. - * - * @throws NamingException If an error occurs - */ - protected void findNamingContext() throws NamingException { - if (getNamingContext() != null) { - getLogger().warn("Overwriting existing naming context."); - } - - // POSSIBLE TO-DO: add support for properties - // passed to the initial context, e.g. a factory, - // to enable things like a remote context. - InitialContext ic = new InitialContext(); - namingContext = (Context) ic.lookup("java:comp/env"); - } - - /** - * @see Action#begin - */ - public void begin( - final ExecutionContext ec, final String name, final Attributes attributes) { - // If first time, create and locate context: expensive operation. - if (getNamingContext() == null) { - try { - findNamingContext(); - } catch (Exception e) { - getLogger().error("Couldn't find JNDI naming context: ", e); - ec.addError(new ErrorItem("Couldn't find JNDI naming context.", e)); - } - } - - String jndiName = attributes.getValue(NAME_ATTRIBUTE); - - if ((jndiName == null) || (jndiName.trim().length() < 1)) { - getLogger().warn("Missing {} attribute, ignoring.", NAME_ATTRIBUTE); - } else if (getNamingContext() != null) { - Object value = null; - - try { - value = getNamingContext().lookup(jndiName); - } catch (Exception e) { - getLogger().error("Error looking up " + jndiName + ": ", e); - ec.addError(new ErrorItem("Error looking up " + jndiName, e)); - } - - if (value == null) { - getLogger().warn("No JNDI value found for {}.", jndiName); - } else if (!(value instanceof String)) { - getLogger().warn("Value for {} is not a String.", jndiName); - } else { - ec.addProperty(jndiName, (String) value); - } - } else { - getLogger().warn("Naming context is null, cannot lookup {}", jndiName); - } - } - - /** - * @see Action#end - */ - public void end(final ExecutionContext ec, final String name) { - } -} - -// End of class: JndiSubstitutionPropertyAction.java diff --git a/src/main/java/org/apache/log4j/joran/action/LayoutAction.java b/src/main/java/org/apache/log4j/joran/action/LayoutAction.java deleted file mode 100644 index e086fbd923..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/LayoutAction.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - - -import org.apache.log4j.Appender; -import org.apache.log4j.Layout; -import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.spi.ErrorItem; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.OptionHandler; - -import org.xml.sax.Attributes; - - -public class LayoutAction extends Action { - Layout layout; - boolean inError = false; - - /** - * Instantiates an layout of the given class and sets its name. - * - */ - public void begin(ExecutionContext ec, String name, Attributes attributes) { - // Let us forget about previous errors (in this object) - inError = false; - - String className = attributes.getValue(CLASS_ATTRIBUTE); - try { - getLogger().debug( - "About to instantiate layout of type [" + className + "]"); - - - layout = (Layout) - OptionConverter.instantiateByClassName( - className, org.apache.log4j.Layout.class, null); - - LoggerRepository repo = (LoggerRepository) ec.getObjectStack().get(0); - layout.setLoggerRepository(repo); - - getLogger().debug("Pushing layout on top of the object stack."); - ec.pushObject(layout); - } catch (Exception oops) { - inError = true; - getLogger().error( - "Could not create an Layout. Reported error follows.", oops); - ec.addError( - new ErrorItem("Could not create layout of type " + className + "].")); - } - } - - /** - * Once the children elements are also parsed, now is the time to activate - * the appender options. - */ - public void end(ExecutionContext ec, String e) { - if (inError) { - return; - } - - layout.activateOptions(); - Object o = ec.peekObject(); - - if (o != layout) { - getLogger().warn( - "The object on the top the of the stack is not the layout pushed earlier."); - } else { - getLogger().debug("Popping layout from the object stack"); - ec.popObject(); - - try { - getLogger().debug( - "About to set the layout of the containing appender."); - Appender appender = (Appender) ec.peekObject(); - appender.setLayout(layout); - } catch (Exception ex) { - getLogger().error( - "Could not set the layout for containing appender.", ex); - } - } - } - - public void finish(ExecutionContext ec) { - } -} diff --git a/src/main/java/org/apache/log4j/joran/action/LevelAction.java b/src/main/java/org/apache/log4j/joran/action/LevelAction.java deleted file mode 100644 index 70d0a09b4a..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/LevelAction.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.apache.log4j.joran.action; - - -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.apache.log4j.helpers.Loader; -import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.spi.ErrorItem; - -import org.xml.sax.Attributes; - -import java.lang.reflect.Method; - - -public class LevelAction extends Action { - - static final String VALUE_ATTR = "value"; - static final String CLASS_ATTR = "class"; - static final String INHERITED = "INHERITED"; - static final String NULL = "NULL"; - static final String EMPTY_STR = ""; - static final Class[] ONE_STRING_PARAM = new Class[] { String.class }; - - public void begin(ExecutionContext ec, String name, Attributes attributes) { - Object o = ec.peekObject(); - - if (!(o instanceof Logger)) { - getLogger().warn("Could not find a logger at the top of execution stack."); - ec.addError( - new ErrorItem( - "For element , could not find a logger at the top of execution stack.")); - - return; - } - - Logger l = (Logger) o; - - String loggerName = l.getName(); - - String levelStr = attributes.getValue(VALUE_ATTR); - getLogger().debug( - "Encapsulating logger name is [" + loggerName + "], levelvalue is [" - + levelStr + "]."); - - if ( - INHERITED.equalsIgnoreCase(levelStr) || NULL.equalsIgnoreCase(levelStr)) { - l.setLevel(null); - } else { - String className = attributes.getValue(CLASS_ATTR); - - if ((className == null) || EMPTY_STR.equals(className)) { - l.setLevel(OptionConverter.toLevel(levelStr, Level.DEBUG)); - } else { - getLogger().debug("Desired Level sub-class: [" + className + ']'); - - try { - Class clazz = Loader.loadClass(className); - Method toLevelMethod = clazz.getMethod("toLevel", ONE_STRING_PARAM); - Level pri = - (Level) toLevelMethod.invoke(null, new Object[] { levelStr }); - l.setLevel(pri); - } catch (Exception oops) { - getLogger().error( - "Could not create level [" + levelStr - + "]. Reported error follows.", oops); - - return; - } - } - } - - getLogger().debug(loggerName + " level set to " + l.getLevel()); - } - - public void finish(ExecutionContext ec) { - } - - public void end(ExecutionContext ec, String e) { - } -} diff --git a/src/main/java/org/apache/log4j/joran/action/LoggerAction.java b/src/main/java/org/apache/log4j/joran/action/LoggerAction.java deleted file mode 100644 index bd621e7619..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/LoggerAction.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - - -import org.apache.log4j.Logger; -import org.apache.log4j.helpers.Loader; -import org.apache.log4j.helpers.Option; -import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.spi.ErrorItem; -import org.apache.log4j.spi.LoggerRepository; - -import org.xml.sax.Attributes; - -import java.lang.reflect.Method; -import java.util.MissingResourceException; -import java.util.ResourceBundle; - - -public class LoggerAction extends Action { - boolean inError = false; - - final static String RESOURCE_BUNDLE = "resourceBundle"; - - public void begin(ExecutionContext ec, String name, Attributes attributes) { - // Let us forget about previous errors (in this object) - inError = false; - - LoggerRepository repository = (LoggerRepository) ec.getObject(0); - - // Create a new org.apache.log4j.Category object from the element. - String loggerName = attributes.getValue(NAME_ATTRIBUTE); - - if (Option.isEmpty(loggerName)) { - inError = true; - - String line = - ", around line " + getLineNumber(ec) + " column " - + getColumnNumber(ec); - - String errorMsg = "No 'name' attribute in element " + name + line; - - getLogger().warn(errorMsg); - ec.addError(new ErrorItem(errorMsg)); - - return; - } - - getLogger().debug("Logger name is [" + loggerName + "]."); - - Logger l; - - String className = attributes.getValue(CLASS_ATTRIBUTE); - - if (Option.isEmpty(className)) { - getLogger().debug("Retreiving an instance of org.apache.log4j.getLogger()."); - l = repository.getLogger(loggerName); - } else { - getLogger().debug("Desired logger sub-class: [" + className + ']'); - - try { - Class clazz = Loader.loadClass(className); - Method getInstanceMethod = - clazz.getMethod("getLogger", ActionConst.ONE_STRING_PARAM); - l = (Logger) getInstanceMethod.invoke( - null, new Object[] { loggerName }); - } catch (Exception oops) { - getLogger().error( - "Could not retrieve category [" + loggerName - + "]. Reported error follows.", oops); - - return; - } - } - - boolean additivity = - OptionConverter.toBoolean( - attributes.getValue(ActionConst.ADDITIVITY_ATTRIBUTE), true); - getLogger().debug( - "Setting [" + l.getName() + "] additivity to [" + additivity + "]."); - l.setAdditivity(additivity); - - getLogger().debug("Pushing logger named [" + loggerName + "]."); - ec.pushObject(l); - - String resourceBundle = attributes.getValue(RESOURCE_BUNDLE); - try { - if (resourceBundle != null) { - ResourceBundle bundle = ResourceBundle.getBundle(resourceBundle); - l.setResourceBundle(bundle); - getLogger().debug( - "Setting [" + l.getName() + "] resourceBundle to [" + resourceBundle + "]."); - } - } catch (MissingResourceException e) { - getLogger().error("Error loading resource bundle [" + resourceBundle + "]", e); - } - } - - public void end(ExecutionContext ec, String e) { - getLogger().debug("end() called."); - - if (!inError) { - getLogger().debug("Removing logger from stack."); - ec.popObject(); - } - } - - public void finish(ExecutionContext ec) { - } -} diff --git a/src/main/java/org/apache/log4j/joran/action/LoggerFactoryAction.java b/src/main/java/org/apache/log4j/joran/action/LoggerFactoryAction.java deleted file mode 100644 index 5a4f11feb8..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/LoggerFactoryAction.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - -import org.apache.log4j.DefaultLoggerFactory; -import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.joran.spi.ActionException; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.spi.LoggerFactory; -import org.apache.log4j.spi.LoggerRepositoryEx; -import org.xml.sax.Attributes; - -public class LoggerFactoryAction extends Action { - - public void begin(ExecutionContext ec, String name, Attributes attributes) throws ActionException { - LoggerRepositoryEx repository = (LoggerRepositoryEx) ec.getObject(0); - String factoryClassName = attributes.getValue(CLASS_ATTRIBUTE); - - if (factoryClassName != null) { - LoggerFactory loggerFactory = - (LoggerFactory) OptionConverter.instantiateByClassName( - factoryClassName, LoggerFactory.class, new DefaultLoggerFactory()); - repository.setLoggerFactory(loggerFactory); - } - else - { - getLogger().warn("Missing " + CLASS_ATTRIBUTE + " for logger factory"); - } - } - - public void end(ExecutionContext ec, String name) throws ActionException { - } - -} diff --git a/src/main/java/org/apache/log4j/joran/action/NestComponentIA.java b/src/main/java/org/apache/log4j/joran/action/NestComponentIA.java deleted file mode 100644 index e29ebc4a83..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/NestComponentIA.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - - -import org.apache.log4j.config.PropertySetter; -import org.apache.log4j.helpers.Loader; -import org.apache.log4j.helpers.Option; -import org.apache.log4j.joran.action.ImplicitAction; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.joran.spi.Pattern; -import org.apache.log4j.spi.Component; -import org.apache.log4j.spi.ErrorItem; -import org.apache.log4j.spi.OptionHandler; - -import org.xml.sax.Attributes; - -import java.util.Stack; - - -/** - * @author Ceki Gülcü - * - */ -public class NestComponentIA extends ImplicitAction { - - // actionDataStack contains ActionData instances - // We use a stack of ActionData objects in order to support nested - // elements which are handled by the same NestComponentIA instance. - // We push a ActionData instance in the isApplicable method (if the - // action is applicable) and pop it in the end() method. - // The XML well-formedness property will guarantee that a push will eventually - // be followed by the corresponding pop. - Stack actionDataStack = new Stack(); - - public boolean isApplicable( - Pattern pattern, Attributes attributes, ExecutionContext ec) { - //LogLog.debug("in NestComponentIA.isApplicable <" + pattern + ">"); - String nestedElementTagName = pattern.peekLast(); - - Object o = ec.peekObject(); - PropertySetter parentBean = new PropertySetter(o); - - int containmentType = parentBean.canContainComponent(nestedElementTagName); - - switch (containmentType) { - case PropertySetter.NOT_FOUND: - return false; - - // we only push action data if NestComponentIA is applicable - case PropertySetter.AS_COLLECTION: - case PropertySetter.AS_PROPERTY: - ActionData ad = new ActionData(parentBean, containmentType); - actionDataStack.push(ad); - - return true; - default: - ec.addError( - new ErrorItem( - "PropertySetter.canContainComponent returned " + containmentType)); - return false; - } - } - - public void begin( - ExecutionContext ec, String localName, Attributes attributes) { - //LogLog.debug("in NestComponentIA begin method"); - // get the action data object pushed in isApplicable() method call - ActionData actionData = (ActionData) actionDataStack.peek(); - - String className = attributes.getValue(CLASS_ATTRIBUTE); - - // perform variable name substitution - className = ec.subst(className); - - if (Option.isEmpty(className)) { - actionData.inError = true; - - String errMsg = "No class name attribute in <" + localName + ">"; - getLogger().error(errMsg); - ec.addError(new ErrorItem(errMsg)); - - return; - } - - try { - getLogger().debug( - "About to instantiate component <{}> of type [{}]", localName, - className); - - actionData.nestedComponent = Loader.loadClass(className).newInstance(); - - // pass along the repository - if(actionData.nestedComponent instanceof Component) { - ((Component) actionData.nestedComponent).setLoggerRepository(this.repository); - } - getLogger().debug( - "Pushing component <{}> on top of the object stack.", localName); - ec.pushObject(actionData.nestedComponent); - } catch (Exception oops) { - actionData.inError = true; - - String msg = "Could not create component <" + localName + ">."; - getLogger().error(msg, oops); - ec.addError(new ErrorItem(msg)); - } - } - - public void end(ExecutionContext ec, String tagName) { - getLogger().debug("entering end method"); - - // pop the action data object pushed in isApplicable() method call - // we assume that each this begin - ActionData actionData = (ActionData) actionDataStack.pop(); - - if (actionData.inError) { - return; - } - - if (actionData.nestedComponent instanceof OptionHandler) { - ((OptionHandler) actionData.nestedComponent).activateOptions(); - } - - Object o = ec.peekObject(); - - if (o != actionData.nestedComponent) { - getLogger().warn( - "The object on the top the of the stack is not the component pushed earlier."); - } else { - getLogger().debug("Removing component from the object stack"); - ec.popObject(); - - // Now let us attach the component - switch (actionData.containmentType) { - case PropertySetter.AS_PROPERTY: - getLogger().debug( - "Setting [{}] to parent of type [{}]", tagName, - actionData.parentBean.getObjClass()); - actionData.parentBean.setComponent( - tagName, actionData.nestedComponent); - - break; - case PropertySetter.AS_COLLECTION: - getLogger().debug( - "Adding [{}] to parent of type [{}]", tagName, - actionData.parentBean.getObjClass()); - actionData.parentBean.addComponent( - tagName, actionData.nestedComponent); - - break; - } - } - } - - public void finish(ExecutionContext ec) { - } -} - - -class ActionData { - PropertySetter parentBean; - Object nestedComponent; - int containmentType; - boolean inError; - - ActionData(PropertySetter parentBean, int containmentType) { - this.parentBean = parentBean; - this.containmentType = containmentType; - } -} diff --git a/src/main/java/org/apache/log4j/joran/action/NewRuleAction.java b/src/main/java/org/apache/log4j/joran/action/NewRuleAction.java deleted file mode 100644 index b3135c595a..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/NewRuleAction.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - - -import org.apache.log4j.helpers.Option; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.joran.spi.Pattern; -import org.apache.log4j.spi.ErrorItem; -import org.xml.sax.Attributes; - - -public class NewRuleAction extends Action { - - /** - * Instantiates an layout of the given class and sets its name. - * - */ - public void begin(ExecutionContext ec, String localName, Attributes attributes) { - String errorMsg; - String pattern = attributes.getValue(Action.PATTERN_ATTRIBUTE); - String actionClass = attributes.getValue(Action.ACTION_CLASS_ATTRIBUTE); - - if(Option.isEmpty(pattern)) { - errorMsg = "No 'pattern' attribute in "; - getLogger().warn(errorMsg); - ec.addError(new ErrorItem(errorMsg)); - return; - } - - if(Option.isEmpty(actionClass)) { - errorMsg = "No 'actionClass' attribute in "; - getLogger().warn(errorMsg); - ec.addError(new ErrorItem(errorMsg)); - return; - } - - try { - getLogger().debug("About to add new Joran parsing rule ["+pattern+","+actionClass+"]."); - ec.getJoranInterpreter().getRuleStore().addRule(new Pattern(pattern), actionClass); - } catch (Exception oops) { - errorMsg = "Could not add new Joran parsing rule ["+pattern+","+actionClass+"]"; - getLogger().error(errorMsg, oops); - ec.addError(new ErrorItem(errorMsg)); - } - } - - /** - * Once the children elements are also parsed, now is the time to activate - * the appender options. - */ - public void end(ExecutionContext ec, String n) { - } - - public void finish(ExecutionContext ec) { - } -} diff --git a/src/main/java/org/apache/log4j/joran/action/ParamAction.java b/src/main/java/org/apache/log4j/joran/action/ParamAction.java deleted file mode 100644 index 16246a16df..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/ParamAction.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - - -import org.apache.log4j.config.PropertySetter; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.spi.ErrorItem; - -import org.xml.sax.Attributes; - - -public class ParamAction extends Action { - static String NO_NAME = "No name attribute in element"; - static String NO_VALUE = "No name attribute in element"; - - public void begin( - ExecutionContext ec, String localName, Attributes attributes) { - String name = attributes.getValue(NAME_ATTRIBUTE); - String value = attributes.getValue(VALUE_ATTRIBUTE); - - if (name == null) { - getLogger().error(NO_NAME); - ec.addError(new ErrorItem(NO_NAME)); - return; - } - - if (value == null) { - getLogger().error(NO_VALUE); - ec.addError(new ErrorItem(NO_VALUE)); - return; - } - - // remove both leading and trailing spaces - value = value.trim(); - - Object o = ec.peekObject(); - PropertySetter propSetter = new PropertySetter(o); - value = ec.subst(value); - - // allow for variable substitution for name as well - name = ec.subst(name); - - getLogger().debug( - "In ParamAction setting parameter [{}] to value [{}].", name, value); - propSetter.setProperty(name, value); - } - - public void end(ExecutionContext ec, String localName) { - } - - public void finish(ExecutionContext ec) { - } -} diff --git a/src/main/java/org/apache/log4j/joran/action/PluginAction.java b/src/main/java/org/apache/log4j/joran/action/PluginAction.java deleted file mode 100644 index 5ecc5f7bce..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/PluginAction.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.joran.action; - - -import org.apache.log4j.helpers.Option; -import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.plugins.Plugin; -import org.apache.log4j.spi.ErrorItem; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggerRepositoryEx; -import org.apache.log4j.spi.OptionHandler; - -import org.xml.sax.Attributes; - -public class PluginAction extends Action { - - Plugin plugin; - boolean inError = false; - - /** - * Instantiates an plugin of the given class and sets its name. - * - * The plugin thus generated is placed in the ExecutionContext plugin bag. - */ - public void begin( - ExecutionContext ec, String localName, Attributes attributes) { - String className = attributes.getValue(CLASS_ATTRIBUTE); - - try { - getLogger().debug( - "About to instantiate plugin of type [" + className + "]"); - - plugin = (Plugin) - OptionConverter.instantiateByClassName( - className, org.apache.log4j.plugins.Plugin.class, null); - - String pluginName = attributes.getValue(NAME_ATTRIBUTE); - - if (Option.isEmpty(pluginName)) { - getLogger().warn( - "No plugin name given for plugin of type " + className + "]."); - } else { - plugin.setName(pluginName); - getLogger().debug("plugin named as [" + pluginName + "]"); - } - - LoggerRepository repository = (LoggerRepository) ec.getObject(0); - - // - // cast may fail when using user supplied repository - // - ((LoggerRepositoryEx) repository).getPluginRegistry().addPlugin(plugin); - plugin.setLoggerRepository(repository); - - getLogger().debug("Pushing plugin on to the object stack."); - ec.pushObject(plugin); - } catch (Exception oops) { - inError = true; - getLogger().error( - "Could not create a plugin. Reported error follows.", oops); - ec.addError( - new ErrorItem( - "Could not create plugin of type " + className + "].")); - } - } - - /** - * Once the children elements are also parsed, now is the time to activate - * the plugin options. - */ - public void end(ExecutionContext ec, String name) { - if (inError) { - return; - } - - plugin.activateOptions(); - Object o = ec.peekObject(); - - if (o != plugin) { - getLogger().warn( - "The object at the of the stack is not the plugin named [" - + plugin.getName() + "] pushed earlier."); - } else { - getLogger().debug( - "Popping plugin named [{}] from the object stack", plugin.getName()); - ec.popObject(); - } - } - - public void finish(ExecutionContext ec) { - } -} diff --git a/src/main/java/org/apache/log4j/joran/action/PriorityAction.java b/src/main/java/org/apache/log4j/joran/action/PriorityAction.java deleted file mode 100644 index 229d5a26ea..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/PriorityAction.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.apache.log4j.joran.action; - - - -import org.apache.log4j.joran.spi.ExecutionContext; -import org.xml.sax.Attributes; - -/** - * This action allows us to warn users that the Priority element has been - * deprecated but is still accepted. - * - * @author Ceki Gulcu - */ -public class PriorityAction extends LevelAction { - public void begin(ExecutionContext ec, String name, Attributes attributes) { - getLogger().warn("Priority element has been deprecated, please use instead."); - super.begin(ec, name, attributes); - } -} diff --git a/src/main/java/org/apache/log4j/joran/action/PropertyAction.java b/src/main/java/org/apache/log4j/joran/action/PropertyAction.java deleted file mode 100644 index 473dc1f76a..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/PropertyAction.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - - -import org.apache.log4j.helpers.Option; -import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.spi.ErrorItem; - -import org.xml.sax.Attributes; - -import java.io.FileInputStream; -import java.io.IOException; - -import java.util.Properties; - -/** - * This class serves as a base for other actions, which similar to the ANT - * task which add/set properties of a given object. - * - * @author Ceki Gülcü - */ -abstract public class PropertyAction extends Action { - static String INVALID_ATTRIBUTES = - "In element, either the \"file\" attribute or both the \"name\" and \"value\" attributes must be set."; - - - abstract void setProperties(ExecutionContext ec, Properties props); - abstract void setProperty(ExecutionContext ec, String key, String value); - - /** - * Set a new property for the execution context by name, value pair, or adds - * all the properties found in the given file. - * - */ - public void begin( - ExecutionContext ec, String localName, Attributes attributes) { - String name = attributes.getValue(NAME_ATTRIBUTE); - String value = attributes.getValue(NAME_ATTRIBUTE); - String fileName = attributes.getValue(FILE_ATTRIBUTE); - - if ( - !Option.isEmpty(fileName) - && (Option.isEmpty(name) && Option.isEmpty(value))) { - Properties props = new Properties(); - - try { - FileInputStream istream = new FileInputStream(fileName); - props.load(istream); - istream.close(); - setProperties(ec, props); - } catch (IOException e) { - String errMsg = "Could not read properties file [" + fileName + "]."; - getLogger().error(errMsg, e); - ec.addError(new ErrorItem(INVALID_ATTRIBUTES, e)); - getLogger().error("Ignoring configuration file [" + fileName + "]."); - - } - } else if ( - !(Option.isEmpty(name) || Option.isEmpty(value)) - && Option.isEmpty(fileName)) { - value = OptionConverter.convertSpecialChars(value); - // now remove both leading and trailing spaces - value = value.trim(); - setProperty(ec, name, value); - } else { - getLogger().error(INVALID_ATTRIBUTES); - ec.addError(new ErrorItem(INVALID_ATTRIBUTES)); - } - } - - public void end(ExecutionContext ec, String name) { - } - - public void finish(ExecutionContext ec) { - } -} diff --git a/src/main/java/org/apache/log4j/joran/action/RepositoryPropertyAction.java b/src/main/java/org/apache/log4j/joran/action/RepositoryPropertyAction.java deleted file mode 100644 index 660a471657..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/RepositoryPropertyAction.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.joran.action; - -import java.util.Properties; - -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggerRepositoryEx; - -/** - * @author ceki - * - * To change the template for this generated type comment go to - * Window>Preferences>Java>Code Generation>Code and Comments - */ -public class RepositoryPropertyAction extends PropertyAction { - - public void setProperties(ExecutionContext ec, Properties props) { - LoggerRepository repository = getLoggerRepository(); - if(repository == null) { - - } - if (repository instanceof LoggerRepositoryEx) { - ((LoggerRepositoryEx) repository).getProperties().putAll(props); - } - } - - public void setProperty(ExecutionContext ec, String key, String value) { - LoggerRepository repository = getLoggerRepository(); - if (repository instanceof LoggerRepositoryEx) { - ((LoggerRepositoryEx) repository).setProperty(key, value); - } - } -} diff --git a/src/main/java/org/apache/log4j/joran/action/RootLoggerAction.java b/src/main/java/org/apache/log4j/joran/action/RootLoggerAction.java deleted file mode 100644 index b96787a90b..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/RootLoggerAction.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - - -import org.apache.log4j.Logger; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.spi.LoggerRepository; - -import org.xml.sax.Attributes; - -public class RootLoggerAction extends Action { - static final String NAME_ATTR = "name"; - static final String CLASS_ATTR = "class"; - static final String ADDITIVITY_ATTR = "additivity"; - static final String EMPTY_STR = ""; - static final Class[] ONE_STRING_PARAM = new Class[] { String.class }; - - Logger root; - boolean inError = false; - - public void begin(ExecutionContext ec, String name, Attributes attributes) { - inError = false; - //logger.debug("In begin method"); - - LoggerRepository repository = (LoggerRepository) ec.getObject(0); - root = repository.getRootLogger(); - - getLogger().debug("Pushing root logger on stack"); - ec.pushObject(root); - } - - public void end(ExecutionContext ec, String name) { - //logger.debug("end() called."); - - if (inError) { - return; - } - - Object o = ec.peekObject(); - - if (o != root) { - getLogger().warn( - "The object on the top the of the stack is not the root logger"); - getLogger().warn("It is: "+o); - } else { - getLogger().debug("Removing root logger from top of stack."); - ec.popObject(); - } - } - - public void finish(ExecutionContext ec) { - } -} diff --git a/src/main/java/org/apache/log4j/joran/action/SubstitutionPropertyAction.java b/src/main/java/org/apache/log4j/joran/action/SubstitutionPropertyAction.java deleted file mode 100644 index 829f8cfe58..0000000000 --- a/src/main/java/org/apache/log4j/joran/action/SubstitutionPropertyAction.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - -import java.util.Properties; - -import org.apache.log4j.joran.spi.ExecutionContext; - - -/** - * This action sets new substitution properties for the execution context by - * name, value pair, or adds all the properties passed in the {@link Properties} - * argument. - * - * @author Ceki Gülcü - */ -public class SubstitutionPropertyAction extends PropertyAction { - - public void setProperties(ExecutionContext ec, Properties props) { - ec.addProperties(props); - } - - public void setProperty(ExecutionContext ec, String key, String value) { - ec.addProperty(key, value); - } -} diff --git a/src/main/java/org/apache/log4j/joran/spi/ActionException.java b/src/main/java/org/apache/log4j/joran/spi/ActionException.java deleted file mode 100644 index 2da8154e5e..0000000000 --- a/src/main/java/org/apache/log4j/joran/spi/ActionException.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.spi; - - -/** - * By throwing an exception an action can signal the Interpreter to skip - * processing, all the nested elements nested within the element throwing the - * exception or skip all following sibling elements in the document. - * - * @author Ceki Gulcu - */ -public class ActionException extends Exception { - /** - * SKIP_CHILDREN signals the {@link Interpreter} to skip processing all the - * nested elements contained within the element causing this ActionException. - */ - public static final int SKIP_CHILDREN = 1; - - /** - * SKIP_SIBLINGS signals the {@link Interpreter} to skip processing all the - * children of this element as well as all the siblings of this elements, - * including any children they may have. - */ - public static final int SKIP_SIBLINGS = 2; - final Throwable rootCause; - final int skipCode; - - public ActionException(final int skipCode) { - this(skipCode, null); - } - - public ActionException(final int skipCode, final Throwable rootCause) { - this.skipCode = skipCode; - this.rootCause = rootCause; - } - - public Throwable getCause() { - return rootCause; - } - - public int getSkipCode() { - return skipCode; - } -} diff --git a/src/main/java/org/apache/log4j/joran/spi/ExecutionContext.java b/src/main/java/org/apache/log4j/joran/spi/ExecutionContext.java deleted file mode 100644 index 983f1967da..0000000000 --- a/src/main/java/org/apache/log4j/joran/spi/ExecutionContext.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.spi; - -//import org.apache.log4j.helpers.OptionConverter; - -import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.spi.ErrorItem; -import org.xml.sax.Locator; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Stack; -import java.util.Vector; - - -/** - * - * The ExecutionContext contains the contextual state of a Joran parsing - * session. {@link org.apache.log4j.joran.action.Action Actions} depend on this - * context to exchange and store information. - * - * @author Ceki Gülcü - */ -public class ExecutionContext { - Stack objectStack; - Map objectMap; - Vector errorList; - Properties substitutionProperties; - Interpreter joranInterpreter; - - public ExecutionContext(Interpreter joranInterpreter) { - this.joranInterpreter = joranInterpreter; - objectStack = new Stack(); - objectMap = new HashMap(5); - errorList = new Vector(); - substitutionProperties = new Properties(); - } - -// /** -// * Clear the internal structures for reuse of the execution context -// * -// */ -// public void clear() { -// objectStack.clear(); -// objectMap.clear(); -// errorList.clear(); -// substitutionProperties.clear(); -// } - - public void addError(ErrorItem errorItem) { - Locator locator = joranInterpreter.getLocator(); - - if (locator != null) { - errorItem.setLineNumber(locator.getLineNumber()); - errorItem.setColNumber(locator.getColumnNumber()); - } - - errorList.add(errorItem); - } - - public List getErrorList() { - return errorList; - } - - public Locator getLocator() { - return joranInterpreter.getLocator(); - } - - public Interpreter getJoranInterpreter() { - return joranInterpreter; - } - - public Stack getObjectStack() { - return objectStack; - } - - public Object peekObject() { - return objectStack.peek(); - } - - public void pushObject(Object o) { - objectStack.push(o); - } - - public Object popObject() { - return objectStack.pop(); - } - - public Object getObject(int i) { - return objectStack.get(i); - } - - public Map getObjectMap() { - return objectMap; - } - - /** - * Add a property to the properties of this execution context. - * If the property exists already, it is overwritten. - */ - public void addProperty(String key, String value) { - if(key == null || value == null) { - return; - } -// if (substitutionProperties.contains(key)) { -// LogLog.warn( -// "key [" + key -// + "] already contained in the EC properties. Overwriting."); -// } - - // values with leading or trailing spaces are bad. We remove them now. - value = value.trim(); - substitutionProperties.put(key, value); - } - - public void addProperties(Properties props) { - if(props == null) { - return; - } - Iterator i = props.keySet().iterator(); - while(i.hasNext()) { - String key = (String) i.next(); - addProperty(key, props.getProperty(key)); - } - } - - public String getSubstitutionProperty(String key) { - return substitutionProperties.getProperty(key); - } - - public String subst(String value) { - if(value == null) { - return null; - } - return OptionConverter.substVars(value, substitutionProperties); - } -} diff --git a/src/main/java/org/apache/log4j/joran/spi/Interpreter.java b/src/main/java/org/apache/log4j/joran/spi/Interpreter.java deleted file mode 100644 index 6ce557d1be..0000000000 --- a/src/main/java/org/apache/log4j/joran/spi/Interpreter.java +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.spi; - -import org.apache.log4j.spi.SimpleULogger; -import org.apache.log4j.joran.action.Action; -import org.apache.log4j.joran.action.ImplicitAction; -import org.apache.log4j.spi.Component; -import org.apache.log4j.spi.ErrorItem; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.ULogger; - -import org.xml.sax.Attributes; -import org.xml.sax.EntityResolver; -import org.xml.sax.InputSource; -import org.xml.sax.Locator; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; -import org.xml.sax.helpers.DefaultHandler; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Stack; -import java.util.Vector; - - -/** - * Interpreter is Joran's main driving class. It extends SAX - * {@link org.xml.sax.helpers.DefaultHandler DefaultHandler} which invokes - * various {@link Action actions} according to predefined patterns. - * - *

    Patterns are kept in a {@link RuleStore} which is programmed to store and - * then later produce the applicable actions for a given pattern. - * - *

    The pattern corresponding to a top level <a> element is the string - * "a". - * - *

    The pattern corresponding to an element <b> embeded within a top level - * <a> element is the string "a/b". - * - *

    The pattern corresponding to an <b> and any level of nesting is - * "*/b. Thus, the * character placed at the beginning of a pattern - * serves as a wildcard for the level of nesting. - * - * Conceptually, this is very similar to the API of commons-digester. Joran - * offers several small advantages. First and foremost, it offers support for - * implicit actions which result in a significant leap in flexibility. Second, - * in our opinion better error reporting capability. Third, it is self-reliant. - * It does not depend on other APIs, in particular commons-logging which is - * a big no-no for log4j. Last but not least, joran is quite tiny and is - * expected to remain so. - * - * @author Ceki Gülcuü - * - */ -public class Interpreter extends DefaultHandler implements Component { - private static List EMPTY_LIST = new Vector(0); - private RuleStore ruleStore; - private ExecutionContext ec; - private ArrayList implicitActions; - Pattern pattern; - Locator locator; - - // The entity resolver is only needed in order to be compatible with - // XML files written for DOMConfigurator containing the following DOCTYPE - // - private EntityResolver entityResolver; - - private LoggerRepository repository; - - /** - * The actionListStack contains a list of actions that are - * executing for the given XML element. - * - * A list of actions is pushed by the {link #startElement} and popped by - * {@link #endElement}. - * - */ - Stack actionListStack; - - /** - * If the skip nested is set, then we skip all its nested elements until - * it is set back to null at when the element's end is reached. - */ - Pattern skip = null; - - public Interpreter(RuleStore rs) { - ruleStore = rs; - ec = new ExecutionContext(this); - implicitActions = new ArrayList(3); - pattern = new Pattern(); - actionListStack = new Stack(); - } - - public ExecutionContext getExecutionContext() { - return ec; - } - - public void startDocument() { - } - - public void startElement( - String namespaceURI, String localName, String qName, Attributes atts) { - - String tagName = getTagName(localName, qName); - - //LogLog.debug("in startElement <" + tagName + ">"); - - pattern.push(tagName); - - List applicableActionList = getApplicableActionList(pattern, atts); - - if (applicableActionList != null) { - actionListStack.add(applicableActionList); - callBeginAction(applicableActionList, tagName, atts); - } else { - actionListStack.add(EMPTY_LIST); - - String errMsg = - "no applicable action for <" + tagName + ">, current pattern is [" - + pattern+"]"; - getLogger().warn(errMsg); - ec.addError(new ErrorItem(errMsg)); - } - } - - public void endElement(String namespaceURI, String localName, String qName) { - List applicableActionList = (List) actionListStack.pop(); - - if(skip != null) { - //System.err.println("In End, pattern is "+pattern+", skip pattern "+skip); - if(skip.equals(pattern)) { - getLogger().info("Normall processing will continue with the next element. Current pattern is <{}>", pattern); - skip = null; - } else { - getLogger().debug("Skipping invoking end() method for <{}>.", pattern); - } - } else if (applicableActionList != EMPTY_LIST) { - callEndAction(applicableActionList, getTagName(localName, qName)); - } - - // given that we always push, we must also pop the pattern - pattern.pop(); - } - - public Locator getLocator() { - return locator; - } - - public void setDocumentLocator(Locator l) { - locator = l; - } - - String getTagName(String localName, String qName) { - String tagName = localName; - - if ((tagName == null) || (tagName.length() < 1)) { - tagName = qName; - } - - return tagName; - } - - public void addImplicitAction(ImplicitAction ia) { - implicitActions.add(ia); - } - - /** - * Check if any implicit actions are applicable. As soon as an applicable - * action is found, it is returned. Thus, the returned list will have at most - * one element. - */ - List lookupImplicitAction(Pattern pattern, Attributes attributes, ExecutionContext ec) { - int len = implicitActions.size(); - - for (int i = 0; i < len; i++) { - ImplicitAction ia = (ImplicitAction) implicitActions.get(i); - - if (ia.isApplicable(pattern, attributes, ec)) { - List actionList = new ArrayList(1); - actionList.add(ia); - - return actionList; - } - } - - return null; - } - - /** - * Return the list of applicable patterns for this - */ - List getApplicableActionList(Pattern pattern, Attributes attributes) { - List applicableActionList = ruleStore.matchActions(pattern); - - //logger.debug("set of applicable patterns: " + applicableActionList); - if (applicableActionList == null) { - applicableActionList = lookupImplicitAction(pattern, attributes, ec); - } - - return applicableActionList; - } - - void callBeginAction( - List applicableActionList, String tagName, Attributes atts) { - if (applicableActionList == null) { - return; - } - - if(skip != null) { - getLogger().debug("Skipping invoking begin() method for <{}>.", pattern); - return; - } - - Iterator i = applicableActionList.iterator(); - - while (i.hasNext()) { - Action action = (Action) i.next(); - - // now let us invoke the action. We catch and report any eventual - // exceptions - try { - action.begin(ec, tagName, atts); - } catch( ActionException ae) { - switch(ae.getSkipCode()) { - case ActionException.SKIP_CHILDREN: - skip = (Pattern) pattern.clone(); - break; - case ActionException.SKIP_SIBLINGS: - skip = (Pattern) pattern.clone(); - // pretend the exception came from one level up. This will cause - // all children and following siblings elements to be skipped - skip.pop(); - break; - } - getLogger().info("Skip pattern set to <{}>", skip); - } catch (Exception e) { - skip = (Pattern) pattern.clone(); - getLogger().info("Skip pattern set to <{}>", skip); - ec.addError(new ErrorItem("Exception in Action for tag <"+tagName+">", e)); - } - } - } - - void callEndAction(List applicableActionList, String tagName) { - if (applicableActionList == null) { - return; - } - - //logger.debug("About to call end actions on node: <" + localName + ">"); - Iterator i = applicableActionList.iterator(); - - while (i.hasNext()) { - Action action = (Action) i.next(); - // now let us invoke the end method of the action. We catch and report - // any eventual exceptions - try { - action.end(ec, tagName); - } catch( ActionException ae) { - switch(ae.getSkipCode()) { - case ActionException.SKIP_CHILDREN: - // after end() is called there can't be any children - break; - case ActionException.SKIP_SIBLINGS: - skip = (Pattern) pattern.clone(); - skip.pop(); - break; - } - getLogger().info("Skip pattern set to <{}>", skip); - } catch(Exception e) { - ec.addError(new ErrorItem("Exception in Action for tag <"+tagName+">", e)); - skip = (Pattern) pattern.clone(); - skip.pop(); // induce the siblings to be skipped - getLogger().info("Skip pattern set to <{}>.", skip); - } - } - } - - public RuleStore getRuleStore() { - return ruleStore; - } - - public void setRuleStore(RuleStore ruleStore) { - this.ruleStore = ruleStore; - } - -// /** -// * Call the finish methods for all actions. Unfortunately, the endDocument -// * method is not called in case of errors in the XML document, which -// * makes endDocument() pretty damn useless. -// */ -// public void endDocument() { -// Set arrayListSet = ruleStore.getActionSet(); -// Iterator iterator = arrayListSet.iterator(); -// while(iterator.hasNext()) { -// ArrayList al = (ArrayList) iterator.next(); -// for(int i = 0; i < al.size(); i++) { -// Action a = (Action) al.get(i); -// a.endDocument(ec); -// } -// } -// } - - public void error(SAXParseException spe) throws SAXException { - ec.addError(new ErrorItem("Parsing error", spe)); - getLogger().error( - "Parsing problem on line " + spe.getLineNumber() + " and column " - + spe.getColumnNumber(), spe); - } - - public void fatalError(SAXParseException spe) throws SAXException { - ec.addError(new ErrorItem("Parsing fatal error", spe)); - getLogger().error( - "Parsing problem on line " + spe.getLineNumber() + " and column " - + spe.getColumnNumber(), spe); - } - - public void warning(SAXParseException spe) throws SAXException { - ec.addError(new ErrorItem("Parsing warning", spe)); - getLogger().warn( - "Parsing problem on line " + spe.getLineNumber() + " and column " - + spe.getColumnNumber(), spe); - } - - public void endPrefixMapping(java.lang.String prefix) { - } - - public void ignorableWhitespace(char[] ch, int start, int length) { - } - - public void processingInstruction( - java.lang.String target, java.lang.String data) { - } - - public void skippedEntity(java.lang.String name) { - } - - public void startPrefixMapping( - java.lang.String prefix, java.lang.String uri) { - } - - public EntityResolver getEntityResolver() { - return entityResolver; - } - - public void setEntityResolver(EntityResolver entityResolver) { - this.entityResolver = entityResolver; - } - - - /** - * If a specific entityResolver is set for this Interpreter instance, then - * we use it to resolve entities. Otherwise, we use the default implementation - * offered by the super class. - * - *

    Due to inexplicable voodoo, the original resolveEntity method in - * org.xml.sax.helpers.DefaultHandler declares throwing an IOException, - * whereas the org.xml.sax.helpers.DefaultHandler class included in - * JDK 1.4 masks this exception. - * - *

    In order to compile under JDK 1.4, we are forced to mask the IOException - * as well. Since its signatures varies, we cannot call our super class' - * resolveEntity method. We are forced to implement the default behavior - * ourselves, which in this case, is just returning null. - * - */ - public InputSource resolveEntity(String publicId, String systemId) throws SAXException { - if(entityResolver == null) { - // the default implementation is to return null - return null; - } else { - try { - return entityResolver.resolveEntity(publicId, systemId); - } catch(IOException ioe) { - // fall back to the default "implementation" - return null; - } - } - } - - public void setLoggerRepository(LoggerRepository repository) { - this.repository = repository; - } - - protected ULogger getLogger() { - if(repository != null) { - return repository.getLogger(this.getClass().getName()); - } else { - return SimpleULogger.getLogger(this.getClass().getName()); - } - } -} diff --git a/src/main/java/org/apache/log4j/joran/spi/JoranDocument.java b/src/main/java/org/apache/log4j/joran/spi/JoranDocument.java deleted file mode 100644 index 28bd40704f..0000000000 --- a/src/main/java/org/apache/log4j/joran/spi/JoranDocument.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.spi; - -import org.apache.log4j.spi.SimpleULogger; -import org.apache.log4j.helpers.Constants; -import org.apache.log4j.spi.ErrorItem; -import org.apache.log4j.spi.LoggerRepository; - -import org.apache.log4j.ULogger; - -import org.xml.sax.Attributes; -import org.xml.sax.ContentHandler; -import org.xml.sax.InputSource; -import org.xml.sax.Locator; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; -import org.xml.sax.helpers.AttributesImpl; -import org.xml.sax.helpers.DefaultHandler; -import org.xml.sax.helpers.LocatorImpl; - -import java.io.ByteArrayInputStream; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - - -/** - * Collects all configuration significant elements from - * an XML parse. - * - * @author Curt Arnold - */ -public final class JoranDocument extends DefaultHandler { - public static final String LOG4J_NS = "http://jakarta.apache.org/log4j/"; - public static final String LS_NS = "http://logging.apache.org/"; - private final List errorList; - private final List events = new ArrayList(20); - private SAXParseException fatalError; - private Locator location; - private final LoggerRepository repository; - - public JoranDocument(final List errorList, LoggerRepository repository) { - this.errorList = errorList; - this.repository = repository; - } - - public void error(final SAXParseException spe) { - errorReport(spe); - } - - public void fatalError(final SAXParseException spe) { - if (fatalError == null) { - fatalError = spe; - } - errorReport(spe); - } - - public void warning(final SAXParseException spe) { - errorReport(spe); - } - - private void errorReport(final SAXParseException spe) { - int line = spe.getLineNumber(); - ErrorItem errorItem = new ErrorItem("Parsing warning", spe); - errorItem.setLineNumber(line); - errorItem.setColNumber(spe.getColumnNumber()); - errorList.add(errorItem); - } - - public void startElement( - final String namespaceURI, final String localName, final String qName, - final Attributes attributes) { - if ( - (namespaceURI == null) || (namespaceURI.length() == 0) - || namespaceURI.equals(LOG4J_NS) || namespaceURI.equals(LS_NS)) { - events.add(new StartElementEvent(localName, location, attributes)); - } - } - - public void endElement( - final String namespaceURI, final String localName, final String qName) { - if ( - (namespaceURI == null) || (namespaceURI.length() == 0) - || namespaceURI.equals(LOG4J_NS) || namespaceURI.equals(LS_NS)) { - events.add(new EndElementEvent(localName, location)); - } - } - - public void replay(final ContentHandler handler) throws SAXException { - if (fatalError != null) { - throw fatalError; - } - LocatorImpl replayLocation = new LocatorImpl(); - handler.setDocumentLocator(replayLocation); - for (Iterator iter = events.iterator(); iter.hasNext();) { - ElementEvent event = (ElementEvent) iter.next(); - event.replay(handler, replayLocation); - } - } - - public InputSource resolveEntity( - final String publicId, final String systemId) throws SAXException { - // - // if log4j.dtd is requested then - // return an empty input source. - // We aren't validating and do not need anything from - // the dtd and do not want a failure if it isn't present. - if ((systemId != null) && systemId.endsWith("log4j.dtd")) { - getLogger().warn("The 'log4j.dtd' is no longer used nor needed."); - getLogger().warn("See {}#log4j_dtd for more details.", Constants.CODES_HREF); - return new InputSource(new ByteArrayInputStream(new byte[0])); - } - - // If the systemId is not for us to handle, we delegate to our super - // class, at leasts that's the basic idea. However, the code below - // needs to be more complicated. - // Due to inexplicable voodoo, the original resolveEntity method in - // org.xml.sax.helpers.DefaultHandler declares throwing an IOException, - // whereas the org.xml.sax.helpers.DefaultHandler class included in - // JDK 1.4 masks this exception. In JDK 1.5, the IOException has been - // put back... - // In order to compile under JDK 1.4, we are forced to mask the IOException - // as well. Since its signatures varies, we cannot call our super class' - // resolveEntity method. We are forced to implement the default behavior - // ourselves, which in this case, is just returning null. - try { - return super.resolveEntity(publicId, systemId); - } catch (Exception e) { - if (e instanceof SAXException) { - throw (SAXException) e; - } else if (e instanceof java.io.IOException) { - // fall back to the default "implementation" - getLogger().error("Default entity resolver threw an IOException", e); - return null; - } else { - // This point should can never be reached. - return null; - } - } - } - - public void setDocumentLocator(Locator location) { - this.location = location; - } - - protected ULogger getLogger() { - if (repository != null) { - return repository.getLogger(this.getClass().getName()); - } else { - return SimpleULogger.getLogger(this.getClass().getName()); - } - } - - private abstract static class ElementEvent { - private String localName; - private Locator location; - - ElementEvent(final String localName, final Locator location) { - this.localName = localName; - if (location != null) { - this.location = new LocatorImpl(location); - } - } - - public final String getLocalName() { - return localName; - } - - public void replay( - final ContentHandler handler, final LocatorImpl replayLocation) - throws SAXException { - if (location != null) { - replayLocation.setPublicId(location.getPublicId()); - replayLocation.setColumnNumber(location.getColumnNumber()); - replayLocation.setLineNumber(location.getLineNumber()); - replayLocation.setSystemId(location.getSystemId()); - } - } - } - - private static class EndElementEvent extends ElementEvent { - public EndElementEvent(final String localName, final Locator location) { - super(localName, location); - } - - public void replay( - final ContentHandler handler, final LocatorImpl replayLocation) - throws SAXException { - super.replay(handler, replayLocation); - handler.endElement( - JoranDocument.LOG4J_NS, getLocalName(), getLocalName()); - } - } - - private static class StartElementEvent extends ElementEvent { - private Attributes attributes; - - public StartElementEvent( - final String localName, final Locator location, - final Attributes attributes) { - super(localName, location); - this.attributes = new AttributesImpl(attributes); - } - - public void replay( - final ContentHandler handler, final LocatorImpl replayLocation) - throws SAXException { - super.replay(handler, replayLocation); - handler.startElement( - JoranDocument.LOG4J_NS, getLocalName(), getLocalName(), attributes); - } - } -} diff --git a/src/main/java/org/apache/log4j/joran/spi/Pattern.java b/src/main/java/org/apache/log4j/joran/spi/Pattern.java deleted file mode 100644 index bfc63441eb..0000000000 --- a/src/main/java/org/apache/log4j/joran/spi/Pattern.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.spi; - -import java.util.ArrayList; - - -public class Pattern implements Cloneable { - - // contains String instances - ArrayList components; - - public Pattern() { - components = new ArrayList(); - } - - public Object clone() { - Pattern p; - try { - p = (Pattern)super.clone(); - } catch (CloneNotSupportedException e) { - throw new Error(); - } - p.components = new ArrayList(components); - return p; - } - - /** - * Build a pattern from a string. - * - * Note that "/x" is considered equivalent to "x" and to "x/" - * - */ - public Pattern(String p) { - this(); - - if (p == null) { - return; - } - - int lastIndex = 0; - - //System.out.println("p is "+ p); - while (true) { - int k = p.indexOf('/', lastIndex); - - //System.out.println("k is "+ k); - if (k == -1) { - components.add(p.substring(lastIndex)); - - break; - } else { - String c = p.substring(lastIndex, k); - - if (c.length() > 0) { - components.add(c); - } - - lastIndex = k + 1; - } - } - - //System.out.println(components); - } - - public void push(String s) { - components.add(s); - } - - public int size() { - return components.size(); - } - - public String get(int i) { - return (String) components.get(i); - } - - public void pop() { - if (!components.isEmpty()) { - components.remove(components.size() - 1); - } - } - - public String peekLast() { - if (!components.isEmpty()) { - int size = components.size(); - return (String) components.get(size - 1); - } else { - return null; - } - } - - /** - * Returns the number of "tail" components that this pattern has in common - * with the pattern p passed as parameter. By "tail" components we mean the - * components at the end of the pattern. - */ - public int tailMatch(Pattern p) { - if (p == null) { - return 0; - } - - int lSize = this.components.size(); - int rSize = p.components.size(); - - // no match possible for empty sets - if ((lSize == 0) || (rSize == 0)) { - return 0; - } - - int minLen = (lSize <= rSize) ? lSize : rSize; - int match = 0; - - // loop from the end to the front - for (int i = 1; i <= minLen; i++) { - String l = (String) this.components.get(lSize - i); - String r = (String) p.components.get(rSize - i); - - if (l.equals(r)) { - match++; - } else { - break; - } - } - - return match; - } - - public boolean equals(Object o) { - //System.out.println("in equals:" +this+ " vs. " + o); - if ((o == null) || !(o instanceof Pattern)) { - return false; - } - - //System.out.println("both are Patterns"); - Pattern r = (Pattern) o; - - if (r.size() != size()) { - return false; - } - - //System.out.println("both are size compatible"); - int len = size(); - - for (int i = 0; i < len; i++) { - if (!(get(i).equals(r.get(i)))) { - return false; - } - } - - // if everything matches, then the twp patterns are equal - return true; - } - - public int hashCode() { - int hc = 0; - int len = size(); - - for (int i = 0; i < len; i++) { - hc ^= get(i).hashCode(); - - //System.out.println("i = "+i+", hc="+hc); - } - - return hc; - } - - public String toString() { - int size = components.size(); - String result = ""; - for(int i = 0; i < size; i++) { - result += "/" + components.get(i); - } - return result; - } -} diff --git a/src/main/java/org/apache/log4j/joran/spi/RuleStore.java b/src/main/java/org/apache/log4j/joran/spi/RuleStore.java deleted file mode 100644 index 64b2ce342d..0000000000 --- a/src/main/java/org/apache/log4j/joran/spi/RuleStore.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.spi; - -import java.util.List; - -import org.apache.log4j.joran.action.Action; - -public interface RuleStore { - public void addRule(Pattern pattern, String actionClassStr) throws ClassNotFoundException; - public void addRule(Pattern pattern, Action action); - - public List matchActions(Pattern pattern); -} diff --git a/src/main/java/org/apache/log4j/joran/spi/SimpleRuleStore.java b/src/main/java/org/apache/log4j/joran/spi/SimpleRuleStore.java deleted file mode 100644 index 17385adbc7..0000000000 --- a/src/main/java/org/apache/log4j/joran/spi/SimpleRuleStore.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.spi; - -import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.joran.action.Action; -import org.apache.log4j.spi.LoggerRepository; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; - - -public class SimpleRuleStore implements RuleStore { - - // key: Pattern instance, value: ArrayList containing actions - HashMap rules = new HashMap(); - LoggerRepository repository; - - public SimpleRuleStore() { - } - - public SimpleRuleStore(LoggerRepository repository) { - this.repository = repository; - } - - /** - * Add a new rule, i.e. a pattern, action pair to the rule store. - *

    - * Note that the added action's LoggerRepository will be set in the - * process. - */ - public void addRule(Pattern pattern, Action action) { - action.setLoggerRepository(repository); - - List a4p = (List) rules.get(pattern); - - if (a4p == null) { - a4p = new ArrayList(); - rules.put(pattern, a4p); - } - - a4p.add(action); - } - - public void addRule(Pattern pattern, String actionClassName) { - Action action = - (Action) OptionConverter.instantiateByClassName( - actionClassName, Action.class, null); - - if(action != null) { - addRule(pattern, action); - } - } - - public List matchActions(Pattern pattern) { - //System.out.println("pattern to search for:" + pattern + ", hashcode: " + pattern.hashCode()); - //System.out.println("rules:" + rules); - ArrayList a4p = (ArrayList) rules.get(pattern); - - if (a4p != null) { - return a4p; - } else { - Iterator patternsIterator = rules.keySet().iterator(); - int max = 0; - Pattern longestMatch = null; - - while (patternsIterator.hasNext()) { - Pattern p = (Pattern) patternsIterator.next(); - - if ((p.size() > 1) && p.get(0).equals("*")) { - int r = pattern.tailMatch(p); - - //System.out.println("tailMatch " +r); - if (r > max) { - //System.out.println("New longest match "+p); - max = r; - longestMatch = p; - } - } - } - - if (longestMatch != null) { - return (ArrayList) rules.get(longestMatch); - } else { - return null; - } - } - } -} diff --git a/src/main/java/org/apache/log4j/lbel/EventEvaluator.java b/src/main/java/org/apache/log4j/lbel/EventEvaluator.java deleted file mode 100644 index f1feb9b3c4..0000000000 --- a/src/main/java/org/apache/log4j/lbel/EventEvaluator.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.lbel; - -import org.apache.log4j.spi.LoggingEvent; - -/** - * An EventEvaluator has the responsability to evaluate whether a given {@link - * LoggingEvent} matches a given criteria. - * - *

    Implementations are free to evaluate the event as they see fit. In - * particular, the evaluation results may depend on previous events. - * - * @author Ceki Gülcü - * @since 1.3 - */ - -public interface EventEvaluator { - - - /** - * Evaluates whether the event passed as parameter matches this evaluator's - * matching criteria. - * - *

    The Evaluator instance is free to evaluate the event as - * it pleases. In particular, the evaluation results may depend on - * previous events. - * - * @param event The event to evaluate - * @return true if there is a match, false otherwise. - * @throws NullPointerException can be thrown in presence of null values - */ - boolean evaluate(LoggingEvent event) throws NullPointerException; -} diff --git a/src/main/java/org/apache/log4j/lbel/LBELEventEvaluator.java b/src/main/java/org/apache/log4j/lbel/LBELEventEvaluator.java deleted file mode 100644 index cbd746a133..0000000000 --- a/src/main/java/org/apache/log4j/lbel/LBELEventEvaluator.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Created on Jan 27, 2005 - * - * To change the template for this generated file go to - * Window>Preferences>Java>Code Generation>Code and Comments - */ -package org.apache.log4j.lbel; - -import java.io.IOException; -import java.io.StringReader; - -import org.apache.log4j.lbel.comparator.Comparator; -import org.apache.log4j.spi.LoggingEvent; - - -/** - * @author Ceki Gülcü - * - */ -public class LBELEventEvaluator implements EventEvaluator { - - private Node top; - - LBELEventEvaluator(String expression) throws ScanError { - StringReader sr = new StringReader(expression); - TokenStream ts = new TokenStream(sr); - Parser parser = new Parser(ts); - try { - top = parser.parse(); - } catch(IOException ioe) { - throw new ScanError("Unexpeted IOException thrown", ioe); - } - } - - public boolean evaluate(LoggingEvent event) { - return evaluate(top, event); - } - - void dumpSyntaxTree(String prefix) { - top.leftFirstDump(prefix); - } - - private boolean evaluate(Node node, LoggingEvent event) { - int type = node.getType(); - boolean left; - switch(type) { - case Node.TRUE: - return true; - case Node.FALSE: - return false; - case Node.COMPARATOR: - return ((Comparator) node.getValue()).compare(event); - case Node.OR: - left = evaluate(node.getLeft(), event); - if(left == true) { - return true; - } else { - return evaluate(node.getRight(), event); - } - case Node.AND: - left = evaluate(node.getLeft(), event); - if(left == false) { - return false; - } else { - return evaluate(node.getRight(), event); - } - case Node.NOT: - return !evaluate(node.getLeft(), event); - } - return false; - } - -} diff --git a/src/main/java/org/apache/log4j/lbel/Node.java b/src/main/java/org/apache/log4j/lbel/Node.java deleted file mode 100644 index 273dc3b4c3..0000000000 --- a/src/main/java/org/apache/log4j/lbel/Node.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.apache.log4j.lbel; - -class Node { - - public static final int FALSE = 1; - public static final int TRUE = 2; - public static final int COMPARATOR = 3; - - public static final int OR = 1000; - public static final int AND = 1100; - public static final int NOT = 1200; - - Node left; - Node right; - - final int type; - final Object value; - - Node(int type) { - this(type, null); - } - - Node(int type, Object value) { - this.type = type; - this.value = value; - } - - public int getType() { - return type; - } - - public Object getValue() { - return value; - } - - public Node getLeft() { - return left; - } - public void setLeft(Node leftSide) { - if(this.left != null) { - throw new IllegalStateException("The left side already set. (old="+this.left+", new="+leftSide+")"); - } - this.left = leftSide; - } - - public Node getRight() { - return right; - } - public void setRight(Node rightSide) { - if(this.right != null) { - throw new IllegalStateException("The right side already set. (old="+this.right+", new="+rightSide+")"); - } - this.right = rightSide; - } - - public String toString() { - return "Node: type="+type+", value="+value; - } - - public void leftFirstDump(String offset) { - - System.out.println(offset + this); - - offset += " "; - - Node l = this.getLeft(); - if(l != null) { - System.out.println(offset +"Printing left side"); - l.leftFirstDump(offset); - } - - //Node m = this.getMiddle(); - //if(m != null) { - //System.out.println(offset +"Printing middle"); - //m.leftFirstDump(offset); - //} - - Node r = this.getRight(); - if(r != null) { - System.out.println(offset +"Printing right side"); - r.leftFirstDump(offset); - } - } -} diff --git a/src/main/java/org/apache/log4j/lbel/Operator.java b/src/main/java/org/apache/log4j/lbel/Operator.java deleted file mode 100644 index 52da3fe4b6..0000000000 --- a/src/main/java/org/apache/log4j/lbel/Operator.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.log4j.lbel; - - -/** - * Operator is an enumeration of known comparison operators. - * - * @author Ceki Gülcü - */ -final public class Operator { - public static final int EQUAL = 1; - public static final int NOT_EQUAL = 2; - - public static final int GREATER = 10; - public static final int GREATER_OR_EQUAL = 11; - - public static final int LESS = 20; - public static final int LESS_OR_EQUAL = 21; - - public static final int REGEX_MATCH = 30; - public static final int NOT_REGEX_MATCH = 31; - - public static final int CHILDOF = 40; - - int code; - - Operator(int code) { - this.code = code; - - switch(code) { - case EQUAL: - case NOT_EQUAL: - case GREATER: - case GREATER_OR_EQUAL: - case LESS: - case LESS_OR_EQUAL: - case REGEX_MATCH: - case NOT_REGEX_MATCH: - case CHILDOF: - break; - default: - new IllegalArgumentException("Unknown operator code ["+code+"]"); - } - } - - public int getCode() { - return code; - } - - public boolean isRegex() { - return (code == REGEX_MATCH) || (code == NOT_REGEX_MATCH); - } - - public String toString() { - switch(code) { - case EQUAL: return "="; - case NOT_EQUAL: return "!="; - case GREATER: return ">"; - case GREATER_OR_EQUAL: return ">="; - case LESS: return "<"; - case LESS_OR_EQUAL: return "<="; - case REGEX_MATCH: return "~"; - case NOT_REGEX_MATCH: return "!~"; - case CHILDOF: return "CHILDOF"; - } - return "UNKNOWN_OPERATOR"; - } - -} diff --git a/src/main/java/org/apache/log4j/lbel/Parser.java b/src/main/java/org/apache/log4j/lbel/Parser.java deleted file mode 100644 index 8e86df135e..0000000000 --- a/src/main/java/org/apache/log4j/lbel/Parser.java +++ /dev/null @@ -1,296 +0,0 @@ -package org.apache.log4j.lbel; - -import java.io.IOException; - -import org.apache.log4j.Level; -import org.apache.log4j.lbel.comparator.ClassComparator; -import org.apache.log4j.lbel.comparator.LevelComparator; -import org.apache.log4j.lbel.comparator.LoggerComparator; -import org.apache.log4j.lbel.comparator.MessageComparator; -import org.apache.log4j.lbel.comparator.MethodComparator; -import org.apache.log4j.lbel.comparator.PropertyComparator; -import org.apache.log4j.lbel.comparator.TimestampComparator; - -/** - * - - - * - * @author Ceki Gülcü - */ -class Parser { - -// The core of LBEL can be summarized by the following grammar. - -// ::= 'OR' -// ::= -// ::= 'AND' -// ::= -// ::= NOT -// ::= '(' ')' -// ::= true -// ::= false - -// In reality takes more varied forms then just true|false but -// from a conceptual point of view, the variations are quite easy to deal with. - -// By eliminating left-recursion, th above grammar can be transformed into the -// following LL(1) form. '#' stands for lambda, that is an empty sequence. - -// ::= -// ::= 'OR' -// ::= # -// ::= -// ::= 'AND' -// ::= # -// ::= NOT -// ::= '(' ')' -// ::= true -// ::= false - -// Which is implemented almost directly by the following top-down parser. - - TokenStream ts; - - Parser(TokenStream bexpTS) { - ts = bexpTS; - } - - Node parse() throws IOException, ScanError { - ts.next(); - return bexp(); - } - - Node bexp() throws IOException, ScanError { - Node result; - Node bterm = bterm(); - Node bexpTail = bexpTail(); - if(bexpTail == null) { - result = bterm; - } else { - result = bexpTail; - result.setLeft(bterm); - } - return result; - } - - Node bexpTail() throws IOException, ScanError { - Token token = ts.getCurrent(); - switch(token.getType()) { - case Token.OR: - ts.next(); - Node or = new Node(Node.OR, "OR"); - - Node bterm = bterm(); - Node bexpTail = bexpTail(); - if(bexpTail == null) { - or.setRight(bterm); - } else { - or.setRight(bexpTail); - bexpTail.setLeft(bterm); - } - return or; - default: - return null; - } - } - - Node bterm() throws IOException, ScanError { - Node result; - Node bfactor = bfactor(); - Node btermTail = btermTail(); - if(btermTail == null) { - result = bfactor; - } else { - result = btermTail; - btermTail.setLeft(bfactor); - } - return result; - } - - Node btermTail() throws IOException, ScanError { - Token token = ts.getCurrent(); - switch(token.getType()) { - case Token.AND: - ts.next(); - Node and = new Node(Node.AND, "AND"); - Node bfactor = bfactor(); - Node btermTail = btermTail(); - if(btermTail == null) { - and.setRight(bfactor); - } else { - and.setRight(btermTail); - btermTail.setLeft(bfactor); - } - return and; - default: - return null; - } - } - - Node bfactor() throws IOException, ScanError { - Token token = ts.getCurrent(); - switch(token.getType()) { - case Token.NOT: - ts.next(); - Node result = new Node(Node.NOT, "NOT"); - Node bsubfactor = bsubfactor(); - result.setLeft(bsubfactor); - return result; - default: - return bsubfactor(); - } - } - - Node bsubfactor() throws IOException, ScanError { - Token token = ts.getCurrent(); - Operator operator; - String literal; - - switch(token.getType()) { - case Token.TRUE: - ts.next(); - return new Node(Node.TRUE, "TRUE"); - case Token.FALSE: - ts.next(); - return new Node(Node.FALSE, "FALSE"); - case Token.LP: - ts.next(); - Node result = bexp(); - Token token2 = ts.getCurrent(); - if(token2.getType() == Token.RP) { - ts.next(); - } else { - throw new IllegalStateException("Expected right parantheses but got" +token); - } - return result; - case Token.LOGGER: - ts.next(); - operator = getOperator(); - ts.next(); - literal = getLiteral(); - return new Node(Node.COMPARATOR, new LoggerComparator(operator, literal)); - case Token.LEVEL: - ts.next(); - operator = getOperator(); - ts.next(); - int levelInt = getLevelInt(); - return new Node(Node.COMPARATOR, new LevelComparator(operator, levelInt)); - case Token.MESSAGE: - ts.next(); - operator = getOperator(); - ts.next(); - literal = getLiteral(); - return new Node(Node.COMPARATOR, new MessageComparator(operator, literal)); - case Token.METHOD: - ts.next(); - operator = getOperator(); - ts.next(); - literal = getLiteral(); - return new Node(Node.COMPARATOR, new MethodComparator(operator, literal)); - case Token.CLASS: - ts.next(); - operator = getOperator(); - ts.next(); - literal = getLiteral(); - return new Node(Node.COMPARATOR, new ClassComparator(operator, literal)); - case Token.TIMESTAMP: - ts.next(); - operator = getOperator(); - ts.next(); - return new Node(Node.COMPARATOR, new TimestampComparator(operator, getLong())); - case Token.PROPERTY: - ts.next(); - String key = (String) getPropertyKey(); - ts.next(); - operator = getOperator(); - ts.next(); - literal = getLiteral(); - return new Node(Node.COMPARATOR, new PropertyComparator(operator, key, literal)); - default: throw new IllegalStateException("Unexpected token " +token); - - } - } - - Operator getOperator() throws ScanError { - Token token = ts.getCurrent(); - if(token.getType() == Token.OPERATOR) { - String value = (String) token.getValue(); - if("=".equals(value)) { - return new Operator(Operator.EQUAL); - } else if("!=".equals(value)) { - return new Operator(Operator.NOT_EQUAL); - } else if(">".equals(value)) { - return new Operator(Operator.GREATER); - } else if(">=".equals(value)) { - return new Operator(Operator.GREATER_OR_EQUAL); - } else if("<".equals(value)) { - return new Operator(Operator.LESS); - } else if("<=".equals(value)) { - return new Operator(Operator.LESS_OR_EQUAL); - } else if("~".equals(value)) { - return new Operator(Operator.REGEX_MATCH); - } else if("!~".equals(value)) { - return new Operator(Operator.NOT_REGEX_MATCH); - } else if("childof".equals(value)) { - return new Operator(Operator.CHILDOF); - } else { - throw new ScanError("Unknown operator type ["+value+"]"); - } - } else { - throw new ScanError("Expected operator token"); - } - } - - String getLiteral() throws ScanError { - Token token = ts.getCurrent(); - if(token.getType() == Token.LITERAL) { - return (String) token.getValue(); - } else if(token.getType() == Token.NULL) { - return null; - } else { - throw new ScanError("Expected LITERAL or NULL but got "+token); - } - } - - long getLong() throws ScanError { - Token token = ts.getCurrent(); - if(token.getType() == Token.NUMBER) { - Long l = (Long) token.getValue(); - return l.longValue(); - } else { - throw new ScanError("Expected LITERAL but got "+token); - } - } - - int getLevelInt() throws ScanError { - String levelStr = getLiteral(); - - if("DEBUG".equalsIgnoreCase(levelStr)) { - return Level.DEBUG_INT; - } else if("INFO".equalsIgnoreCase(levelStr)) { - return Level.INFO_INT; - } else if("WARN".equalsIgnoreCase(levelStr)) { - return Level.WARN_INT; - } else if("ERROR".equalsIgnoreCase(levelStr)) { - return Level.ERROR_INT; - } else { - throw new ScanError("Expected a level stirng got "+levelStr); - } - } - - String getPropertyKey() throws IOException, ScanError { - Token token = ts.getCurrent(); - if(token.getType() == Token.DOT) { - ts.next(); - Token token2 = ts.getCurrent(); - if(token2.getType() == Token.LITERAL) { - return (String) token2.getValue(); - } else { - throw new ScanError("Expected LITERAL but got "+token2); - } - } else { - throw new ScanError("Expected '.' but got "+token); - } - } -} diff --git a/src/main/java/org/apache/log4j/lbel/ScanError.java b/src/main/java/org/apache/log4j/lbel/ScanError.java deleted file mode 100644 index 232ceafc45..0000000000 --- a/src/main/java/org/apache/log4j/lbel/ScanError.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.apache.log4j.lbel; - -public class ScanError extends Exception { - - Throwable cause; - - public ScanError(String msg) { - super(msg); - } - - public ScanError(String msg, Throwable rootCause) { - super(msg); - this.cause = rootCause; - } - - public Throwable getCause() { - return cause; - } -} diff --git a/src/main/java/org/apache/log4j/lbel/Token.java b/src/main/java/org/apache/log4j/lbel/Token.java deleted file mode 100644 index 66b775761f..0000000000 --- a/src/main/java/org/apache/log4j/lbel/Token.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.apache.log4j.lbel; - - -class Token { - - private int type; - private Object value; - public static final int TRUE = 1; - public static final int FALSE = 2; - public static final int OR = 10; - public static final int AND = 11; - public static final int NOT = 12; - public static final int LITERAL = 20; - public static final int NUMBER = 21; - public static final int OPERATOR = 30; - public static final int LP = 40; - public static final int RP = 41; - - public static final int LOGGER = 100; - public static final int MESSAGE = 110; - public static final int LEVEL = 120; - public static final int TIMESTAMP = 130; - public static final int THREAD = 140; - public static final int PROPERTY = 150; - public static final int DATE = 160; - - public static final int CLASS = 170; - public static final int METHOD = 180; - public static final int NULL = 190; - public static final int DOT = 200; - - public static final int EOF = 1000; - - public Token(int type) { - this(type, null); - } - - public Token(int type, Object value) { - this.type = type; - this.value = value; - } - - - - public int getType() { - return type; - } - - public Object getValue() { - return value; - } - - public String toString() { - String typeStr = null; - switch(type) { - - case TRUE: typeStr = "TRUE"; break; - case FALSE: typeStr = "FALSE"; break; - case OR: typeStr = "OR"; break; - case AND: typeStr = "AND"; break; - case NOT: typeStr = "NOT"; break; - case LITERAL: typeStr = "IDENTIFIER"; break; - case NUMBER: typeStr = "NUMBER"; break; - case OPERATOR: typeStr = "OPERATOR"; break; - case LP: typeStr = "LP"; break; - case RP: typeStr = "RP"; break; - case LOGGER: typeStr = "LOGGER"; break; - case MESSAGE: typeStr = "MESSAGE"; break; - case LEVEL: typeStr = "LEVEL"; break; - case TIMESTAMP: typeStr = "TIMESTAMP"; break; - case THREAD: typeStr = "THREAD"; break; - case PROPERTY: typeStr = "PROPERTY"; break; - case DATE: typeStr = "DATE"; break; - case EOF: typeStr = "EOF"; break; - default: typeStr = "UNKNOWN"; - } - return "Token("+typeStr +", " + value+")"; - } -} diff --git a/src/main/java/org/apache/log4j/lbel/TokenStream.java b/src/main/java/org/apache/log4j/lbel/TokenStream.java deleted file mode 100644 index 7f507d21f2..0000000000 --- a/src/main/java/org/apache/log4j/lbel/TokenStream.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.lbel; - - -import java.io.IOException; -import java.io.Reader; -import java.io.StreamTokenizer; -import java.util.HashMap; -import java.util.Map; - - -class TokenStream { - - // keywordMap contains a map of keywords - // key = keyword string - // value = token corresponding to the keyword - private static Map keywordMap = new HashMap(); - - static { - keywordMap.put("true", new Token(Token.TRUE)); - keywordMap.put("false", new Token(Token.FALSE)); - keywordMap.put("not", new Token(Token.NOT)); - keywordMap.put("and", new Token(Token.AND)); - keywordMap.put("or", new Token(Token.OR)); - keywordMap.put("childof", new Token(Token.OPERATOR, "childof")); - keywordMap.put("logger", new Token(Token.LOGGER, "logger")); - keywordMap.put("message", new Token(Token.MESSAGE, "message")); - keywordMap.put("level", new Token(Token.LEVEL, "level")); - keywordMap.put("method", new Token(Token.METHOD, "method")); - keywordMap.put("class", new Token(Token.CLASS, "class")); - keywordMap.put("thread", new Token(Token.THREAD, "thread")); - keywordMap.put("property", new Token(Token.PROPERTY, "property")); - keywordMap.put("date", new Token(Token.DATE, "date")); - keywordMap.put("null", new Token(Token.NULL, "null")); - } - - StreamTokenizer tokenizer; - int token; - Token current; - Reader reader; - - public TokenStream(Reader reader) { - this.reader = reader; - tokenizer = new StreamTokenizer(reader); - tokenizer.resetSyntax(); - - tokenizer.whitespaceChars(' ', ' '); - tokenizer.whitespaceChars('\t', '\t'); - tokenizer.whitespaceChars('\n', '\n'); - tokenizer.whitespaceChars('\r', '\r'); - - tokenizer.wordChars('a', 'z'); - tokenizer.wordChars('A', 'Z'); - tokenizer.wordChars('0', '9'); - - - - // StreamTokenizer does not correctly handle the '\' character within quotes - // tokenizer.quoteChar('"'); - // tokenizer.quoteChar('\''); - - tokenizer.parseNumbers(); - tokenizer.ordinaryChar('.'); - } - - public Token getCurrent() { - return current; - } - - public void next() throws IOException, ScanError { - int token2; - - if(token != StreamTokenizer.TT_EOF) { - token = tokenizer.nextToken(); - switch(token) { - case StreamTokenizer.TT_EOF: - current = new Token(Token.EOF); - break; - case StreamTokenizer.TT_NUMBER: - double nval = tokenizer.nval; - current = new Token(Token.NUMBER, new Long((long) nval)); - break; - case StreamTokenizer.TT_WORD: - String txt = tokenizer.sval; - String lowerCaseTxt = txt.toLowerCase(); - Token result = (Token) keywordMap.get(lowerCaseTxt); - if(result != null) { - current = result; - } else { - current = new Token(Token.LITERAL, tokenizer.sval); - } - break; - case '"': - case '\'': - current = scanLiteral(token); - break; - case '.': - current = new Token(Token.DOT, "."); - break; - case '>': - token2 = tokenizer.nextToken(); - if(token2 == '=') { - current = new Token(Token.OPERATOR, ">="); - } else { - current = new Token(Token.OPERATOR, ">"); - tokenizer.pushBack(); - } - break; - case '<': - token2 = tokenizer.nextToken(); - if(token2 == '=') { - current = new Token(Token.OPERATOR, "<="); - } else { - current = new Token(Token.OPERATOR, "<"); - tokenizer.pushBack(); - } - break; - case '=': - current = new Token(Token.OPERATOR, "="); - break; - case '~': - current = new Token(Token.OPERATOR, "~"); - break; - case '!': - token2 = tokenizer.nextToken(); - if(token2 == '=') { - current = new Token(Token.OPERATOR, "!="); - } else if (token2 == '~') { - current = new Token(Token.OPERATOR, "!~"); - } else { - throw new ScanError("Unrecogized token "+token+". The '!' character must be followed by = or '~'"); - } - break; - case '(': - current = new Token(Token.LP); - break; - case ')': - current = new Token(Token.RP); - break; - default: - throw new ScanError("Unrecogized token ["+(char)token+"]"); - } - - } - } - - Token scanLiteral(int startChar) { - StringBuffer buf = new StringBuffer(); - try { - int in = 0; - while(in != -1) { - in = reader.read(); - if(in == startChar) { - break; - } else { - switch(in) { - case '\n': - case '\r': - break; // ignore line breaks - default: buf.append((char) in); - } - } - } - } catch(IOException io) { - } - - return new Token(Token.LITERAL, buf.toString()); - } - - // Token extractPropertyToken() throws ScanError { -// int token = tokenizer.nextToken(); -// if(token == '.') { -// } -// -// int point = txt.indexOf('.'); -// String key = txt.substring(point+1); -// // Is the key empty? (An empty key is the only thing that can go wrong at -// // this stage. -// if(key == null || key.length() == 0) { -// throw new ScanError("["+txt+"] has zero-legnth key."); -// } else { -// return new Token(Token.PROPERTY, key); -// } - // } -} diff --git a/src/main/java/org/apache/log4j/lbel/comparator/ClassComparator.java b/src/main/java/org/apache/log4j/lbel/comparator/ClassComparator.java deleted file mode 100644 index 2ee13491a5..0000000000 --- a/src/main/java/org/apache/log4j/lbel/comparator/ClassComparator.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.lbel.comparator; - -import org.apache.log4j.lbel.Operator; -import org.apache.log4j.lbel.ScanError; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.LocationInfo; - - -/** - * Compare the class of an event passed as parameter to the class name and - * comparison operator set in the constructor. - * - *

    Allowed comparison operators are '=', '!=', '>', '>=', '<', '<=', '~' and - * '!~' where '~' stands for regular expression match. - * - * @author Ceki Gülcü - */ -public class ClassComparator extends StringComparator { - - public ClassComparator(final Operator operator, String rightSide) - throws ScanError { - super(operator, rightSide); - } - - protected String getLeftSide(LoggingEvent event) { - LocationInfo li = event.getLocationInformation(); - return li.getClassName(); - } -} diff --git a/src/main/java/org/apache/log4j/lbel/comparator/Comparator.java b/src/main/java/org/apache/log4j/lbel/comparator/Comparator.java deleted file mode 100644 index 5f0aecce9e..0000000000 --- a/src/main/java/org/apache/log4j/lbel/comparator/Comparator.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.lbel.comparator; - -import org.apache.log4j.spi.LoggingEvent; - - -/** - * A Comparator instance is a node in the syntax tree returned by the parser. - * It compares events according to criteria proper to the comparator. - * - * @author Ceki Gülcü - * - */ -public interface Comparator { - - /** - * - * @param event - * @return - * @throws NullPointerException thrown if the lef or right side is null and - * the comparison operator is other than equals not equals ('=' or '!='). - */ - public boolean compare(LoggingEvent event) throws NullPointerException; -} diff --git a/src/main/java/org/apache/log4j/lbel/comparator/LevelComparator.java b/src/main/java/org/apache/log4j/lbel/comparator/LevelComparator.java deleted file mode 100644 index 53fc83364f..0000000000 --- a/src/main/java/org/apache/log4j/lbel/comparator/LevelComparator.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.lbel.comparator; - -import org.apache.log4j.lbel.Operator; -import org.apache.log4j.spi.LoggingEvent; - - -/** - * Compare the level of an event passed as parameter to the level set in the - * constructor. - * - * @author Ceki Gülcü - */ -public class LevelComparator implements Comparator { - - Operator operator; - int rightLevel; - - /** - * This constructor is called by the parser. - * - * @param operator the comparison operator to use - * @param level the level (in integer form) to compare to - */ - public LevelComparator(Operator operator, int level) { - this.operator = operator; - this.rightLevel = level; - } - - /** - * Compare the level event passed as parameter with the level of this instance - * according to the operator of this instance. - */ - public boolean compare(LoggingEvent event) { - int leftLevel = event.getLevel().toInt(); - - switch(operator.getCode()) { - case Operator.EQUAL: return leftLevel == rightLevel; - case Operator.NOT_EQUAL: return leftLevel != rightLevel; - case Operator.GREATER: return leftLevel > rightLevel; - case Operator.GREATER_OR_EQUAL: return leftLevel >= rightLevel; - case Operator.LESS: return leftLevel < rightLevel; - case Operator.LESS_OR_EQUAL: return leftLevel <= rightLevel; - } - throw new IllegalStateException("Unreachable state reached, operator "+operator); - } -} diff --git a/src/main/java/org/apache/log4j/lbel/comparator/LoggerComparator.java b/src/main/java/org/apache/log4j/lbel/comparator/LoggerComparator.java deleted file mode 100644 index ee08c8e57e..0000000000 --- a/src/main/java/org/apache/log4j/lbel/comparator/LoggerComparator.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.lbel.comparator; - -import org.apache.log4j.lbel.Operator; -import org.apache.log4j.lbel.ScanError; -import org.apache.log4j.spi.LoggingEvent; - - -/** - * Compare the logger of an event passed as parameter to the logger name and - * comparison operator set in the constructor. - * - *

    Allowed comparison operators are '=', '!=', '>', '>=', '<', '<=', '~' and - * '!~' where '~' stands for regular expression match. - * - * @author Ceki Gülcü - * @author Scott Deboy - */ -public class LoggerComparator extends StringComparator { - public LoggerComparator(final Operator operator, String rightSide) - throws ScanError { - super(operator, rightSide); - } - - protected String getLeftSide(LoggingEvent event) { - return event.getLoggerName(); - } -} diff --git a/src/main/java/org/apache/log4j/lbel/comparator/MessageComparator.java b/src/main/java/org/apache/log4j/lbel/comparator/MessageComparator.java deleted file mode 100644 index 2502f200f2..0000000000 --- a/src/main/java/org/apache/log4j/lbel/comparator/MessageComparator.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.lbel.comparator; - -import org.apache.log4j.lbel.Operator; -import org.apache.log4j.lbel.ScanError; -import org.apache.log4j.spi.LoggingEvent; - - -/** - * Compare the message of an event passed as parameter to the logger name and - * comparison operator set in the constructor. - * - *

    Allowed comparison operators are '=', '!=', '>', '>=', '<', '<=', '~' and - * '!~' where '~' stands for regular expression match. - * - * @author Ceki Gülcü - * @author Scott Deboy - */ -public class MessageComparator extends StringComparator { - public MessageComparator(final Operator operator, String rightSide) - throws ScanError { - super(operator, rightSide); - } - - protected String getLeftSide(LoggingEvent event) { - return event.getRenderedMessage(); - } -} diff --git a/src/main/java/org/apache/log4j/lbel/comparator/MethodComparator.java b/src/main/java/org/apache/log4j/lbel/comparator/MethodComparator.java deleted file mode 100644 index f6bc81b9e5..0000000000 --- a/src/main/java/org/apache/log4j/lbel/comparator/MethodComparator.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.lbel.comparator; - -import org.apache.log4j.lbel.Operator; -import org.apache.log4j.lbel.ScanError; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.LocationInfo; - - -/** - * Compare the method of an event passed as parameter to the method name and - * comparison operator set in the constructor. - * - *

    Allowed comparison operators are '=', '!=', '>', '>=', '<', '<=', '~' and - * '!~' where '~' stands for regular expression match. - * - * @author Ceki Gülcü - */ -public class MethodComparator extends StringComparator { - - public MethodComparator(final Operator operator, String rightSide) - throws ScanError { - super(operator, rightSide); - } - - protected String getLeftSide(LoggingEvent event) { - LocationInfo li = event.getLocationInformation(); - return li.getMethodName(); - } -} diff --git a/src/main/java/org/apache/log4j/lbel/comparator/PropertyComparator.java b/src/main/java/org/apache/log4j/lbel/comparator/PropertyComparator.java deleted file mode 100644 index 94e4f5d371..0000000000 --- a/src/main/java/org/apache/log4j/lbel/comparator/PropertyComparator.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.lbel.comparator; - -import org.apache.log4j.lbel.Operator; -import org.apache.log4j.lbel.ScanError; -import org.apache.log4j.spi.LoggingEvent; - -/** - * Compare a property of an event passed as parameter to the string value and - * comparison operator set in the constructor. - * - *

    Allowed comparison operators are '=', '!=', '>', '>=', '<', '<=', '~' and - * '!~' where '~' stands for regular expression match. - * - * @author Ceki Gülcü - * @author Scott Deboy - */ -public class PropertyComparator extends StringComparator { - String key; - - public PropertyComparator(final Operator operator, String key, String rightSide) - throws ScanError { - super(operator, rightSide); - this.key = key; - } - - protected String getLeftSide(LoggingEvent event) { - return event.getProperty(key); - } - - public String toString() { - return "PropertyComparator("+key+","+operator+", "+rightSide+")"; - } -} diff --git a/src/main/java/org/apache/log4j/lbel/comparator/StringComparator.java b/src/main/java/org/apache/log4j/lbel/comparator/StringComparator.java deleted file mode 100644 index bf5f5b43bf..0000000000 --- a/src/main/java/org/apache/log4j/lbel/comparator/StringComparator.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.lbel.comparator; - -import org.apache.log4j.lbel.Operator; -import org.apache.log4j.lbel.ScanError; -import org.apache.log4j.spi.LoggingEvent; - -import org.apache.oro.text.regex.MalformedPatternException; -import org.apache.oro.text.regex.Pattern; -import org.apache.oro.text.regex.Perl5Compiler; -import org.apache.oro.text.regex.Perl5Matcher; - - -/** - * Base class for string-based comparators. - * - *

    Allowed comparison operators are 'CHILDOF', '=', '!=', '>', '>=', '<', - * '<=', '~' and '!~' where '~' stands for regular expression match. - * - * @author Ceki Gülcü - * @author Scott Deboy - */ -public abstract class StringComparator implements Comparator { - Operator operator; - String rightSide; - String rightSideWithDotSuffix; - Pattern rightSidePattern; - Perl5Matcher matcher; - - public StringComparator(Operator operator, String rightSide) - throws ScanError { - this.operator = operator; - this.rightSide = rightSide; - - if (operator.isRegex()) { - Perl5Compiler compiler = new Perl5Compiler(); - matcher = new Perl5Matcher(); - try { - rightSidePattern = compiler.compile(rightSide); - } catch (MalformedPatternException mfpe) { - throw new ScanError("Malformed pattern [" + rightSide + "]", mfpe); - } - } - - // if CHILDOF operator and rightSide does not end with a dot add one - if ((operator.getCode() == Operator.CHILDOF) && !rightSide.endsWith(".")) { - this.rightSideWithDotSuffix = rightSide + "."; - } - } - - /** - * Derived classes supply the left side of the comparison based on the event. - * - * @param event - * @return the left side of the expression - */ - protected abstract String getLeftSide(LoggingEvent event); - - public boolean compare(LoggingEvent event) throws NullPointerException { - String leftSide = getLeftSide(event); - - if (leftSide == null) { - switch (operator.getCode()) { - case Operator.EQUAL: - return leftSide == rightSide; - case Operator.NOT_EQUAL: - return leftSide != rightSide; - default: - throw new NullPointerException( - "null leftside can only be used with == or != operators"); - } - } - - if (operator.isRegex()) { - boolean match = matcher.contains(leftSide, rightSidePattern); - if (operator.getCode() == Operator.REGEX_MATCH) { - return match; - } else { - return !match; - } - } - - if (operator.getCode() == Operator.CHILDOF) { - if (leftSide.equals(rightSide)) { - return true; - } else { - return leftSide.startsWith(rightSideWithDotSuffix); - } - } - - if (rightSide == null) { - switch (operator.getCode()) { - case Operator.EQUAL: - return leftSide == rightSide; - case Operator.NOT_EQUAL: - return leftSide != rightSide; - default: - throw new NullPointerException( - "null rightside can only be used with == or != operators"); - } - } - int compResult = leftSide.compareTo(rightSide); - - switch (operator.getCode()) { - case Operator.EQUAL: - return compResult == 0; - case Operator.NOT_EQUAL: - return compResult != 0; - case Operator.GREATER: - return compResult > 0; - case Operator.GREATER_OR_EQUAL: - return compResult >= 0; - case Operator.LESS: - return compResult < 0; - case Operator.LESS_OR_EQUAL: - return compResult <= 0; - } - - throw new IllegalStateException( - "Unreachable state reached, operator " + operator); - } - - public String toString() { - String full = this.getClass().getName(); - int i = full.lastIndexOf("."); - return full.substring(i) + "(" + operator + ", " + rightSide + ")"; - } -} diff --git a/src/main/java/org/apache/log4j/lbel/comparator/TimestampComparator.java b/src/main/java/org/apache/log4j/lbel/comparator/TimestampComparator.java deleted file mode 100644 index cf909a3266..0000000000 --- a/src/main/java/org/apache/log4j/lbel/comparator/TimestampComparator.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.lbel.comparator; - -import org.apache.log4j.lbel.Operator; -import org.apache.log4j.spi.LoggingEvent; - - -/** - * Compare the timestamp of - * - * @author Ceki Gülcü - */ -public class TimestampComparator implements Comparator { - - Operator operator; - long rightTimestamp; - - public TimestampComparator(Operator operator, long rightTimestamp) { - this.operator = operator; - this.rightTimestamp = rightTimestamp; - - } - - public boolean compare(LoggingEvent event) { - long leftTimestamp = event.getTimeStamp(); - - switch(operator.getCode()) { - case Operator.EQUAL: return leftTimestamp == rightTimestamp; - case Operator.NOT_EQUAL: return leftTimestamp != rightTimestamp; - case Operator.GREATER: return leftTimestamp > rightTimestamp; - case Operator.GREATER_OR_EQUAL: return leftTimestamp >= rightTimestamp; - case Operator.LESS: return leftTimestamp < rightTimestamp; - case Operator.LESS_OR_EQUAL: return leftTimestamp <= rightTimestamp; - } - throw new IllegalStateException("Unreachable state reached, "+operator); - } -} diff --git a/src/main/java/org/apache/log4j/multiplex/AppenderFactory.java b/src/main/java/org/apache/log4j/multiplex/AppenderFactory.java deleted file mode 100644 index 2ceca0c927..0000000000 --- a/src/main/java/org/apache/log4j/multiplex/AppenderFactory.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.apache.log4j.multiplex; - -import org.apache.log4j.Appender; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.OptionHandler; - -/** - * @author psmith - * - */ - -public interface AppenderFactory extends OptionHandler{ - - public Appender create(LoggingEvent e); -} diff --git a/src/main/java/org/apache/log4j/multiplex/AppenderFactoryUtils.java b/src/main/java/org/apache/log4j/multiplex/AppenderFactoryUtils.java deleted file mode 100644 index 8985f21fb9..0000000000 --- a/src/main/java/org/apache/log4j/multiplex/AppenderFactoryUtils.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.apache.log4j.multiplex; - -import java.text.MessageFormat; - -import org.apache.log4j.Appender; -import org.apache.log4j.FileAppender; -import org.apache.log4j.Layout; -import org.apache.log4j.PatternLayout; -import org.apache.log4j.rolling.RollingFileAppender; -import org.apache.log4j.rolling.TimeBasedRollingPolicy; -import org.apache.log4j.spi.LoggingEvent; - -/** - * @author psmith - * - */ -public class AppenderFactoryUtils { - - public static AppenderFactory createMDCAndDailyRollingAppenderFactory( - final String fullFilePathAndPrefix, final String mdcKey, - final Layout layout) { - return new AppenderFactory() { - - public void activateOptions() { - - } - - public Appender create(LoggingEvent e) { - String value = e.getProperty(mdcKey); - - String datePattern = "yyyy-MM-dd"; - - TimeBasedRollingPolicy tbrp = new TimeBasedRollingPolicy(); - String pattern = fullFilePathAndPrefix + "-" + value + "-%d{" - + datePattern + "}"; - - tbrp.setFileNamePattern(pattern); - tbrp.activateOptions(); - RollingFileAppender rfa = new RollingFileAppender(); - rfa.setRollingPolicy(tbrp); - rfa.activateOptions(); - return rfa; - - } - - }; - - } - - private AppenderFactoryUtils() { - } - - /** - * @param mdcKey - * @param layout - * @return - */ - public static AppenderFactory createSimpleMDCbasedFileAppender( - final String fullFilePathAndPrefix, final String mdcKey, - final PatternLayout layout) { - return new AppenderFactory() { - - public Appender create(LoggingEvent e) { - String value = e.getProperty(mdcKey); - String pattern = fullFilePathAndPrefix + "_{0}.log"; - try { - FileAppender fileAppender = new FileAppender(layout, - MessageFormat.format(pattern, - new Object[] { value })); - fileAppender.activateOptions(); - return fileAppender; - } catch (Exception ex) { - //throw new RuntimeException(ex); - throw new RuntimeException(); - - } - } - - public void activateOptions() { - - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/multiplex/MDCKeySelector.java b/src/main/java/org/apache/log4j/multiplex/MDCKeySelector.java deleted file mode 100644 index 0a6b9e279e..0000000000 --- a/src/main/java/org/apache/log4j/multiplex/MDCKeySelector.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.apache.log4j.multiplex; - -import org.apache.log4j.Appender; -import org.apache.log4j.spi.LoggingEvent; - -/** - * @author psmith - * - */ -public class MDCKeySelector extends MultiplexSelectorSkeleton { - - private String MDCKey; - - /** - * @param key - */ - public MDCKeySelector(String key) { - super(); - MDCKey = key; - } - - /** - * @return Returns the mDCKey. - */ - public final String getMDCKey() { - return MDCKey; - } - - /* - * (non-Javadoc) - * - * @see org.apache.log4j.multiplex.MultiplexSelector#select(org.apache.log4j.spi.LoggingEvent) - */ - public Appender select(LoggingEvent e) { - return lookupOrCreateAsNeeded(e.getProperty(getMDCKey()), e); - } - - /** - * @param key - * The mDCKey to set. - */ - public final void setMDCKey(String key) { - MDCKey = key; - } - - /* (non-Javadoc) - * @see org.apache.log4j.spi.OptionHandler#activateOptions() - */ - public void activateOptions() { - - // TODO ? - } - -} \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/multiplex/MultiplexAppender.java b/src/main/java/org/apache/log4j/multiplex/MultiplexAppender.java deleted file mode 100644 index 3813476b56..0000000000 --- a/src/main/java/org/apache/log4j/multiplex/MultiplexAppender.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.apache.log4j.multiplex; - -import org.apache.log4j.Appender; -import org.apache.log4j.AppenderSkeleton; -import org.apache.log4j.spi.LoggingEvent; - -/** - * - * TODO discuss how the Selector and AppenderFactory works - * - * - * @author psmith - * - */ -public class MultiplexAppender extends AppenderSkeleton { - - private MultiplexSelector selector; - - public MultiplexAppender() { - super(true); - } - /* - * (non-Javadoc) - * - * @see org.apache.log4j.spi.OptionHandler#activateOptions() - */ - public void activateOptions() { - - - // check that we have a selector of something at this point - if (getSelector() == null) { - throw new IllegalStateException( - "Should have had a Selector defined at this point"); - } - - // TODO work out how the Selector has it's AppenderFactory configured by Joran - } - - /* - * (non-Javadoc) - * - * @see org.apache.log4j.Appender#close() - */ - public void close() { - getSelector().close(); - - } - - /** - * @return Returns the selector. - */ - public final MultiplexSelector getSelector() { - return selector; - } - - /* - * (non-Javadoc) - * - * @see org.apache.log4j.Appender#requiresLayout() - */ - public boolean requiresLayout() { - // TODO check this is correct - return true; - } - - /** - * @param selector - * The selector to set. - */ - public final void setSelector(MultiplexSelector selector) { - this.selector = selector; - } - - /* - * (non-Javadoc) - * - * @see org.apache.log4j.WriterAppender#subAppend(org.apache.log4j.spi.LoggingEvent) - */ - protected void append(LoggingEvent event) { - - // we assume appropriate syncronization has occured on this appender - - // determinge the key to lookup the Appender to use - Appender appender = getSelector().select(event); - appender.doAppend(event); - - } -} \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/multiplex/MultiplexSelector.java b/src/main/java/org/apache/log4j/multiplex/MultiplexSelector.java deleted file mode 100644 index aad6802f05..0000000000 --- a/src/main/java/org/apache/log4j/multiplex/MultiplexSelector.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.apache.log4j.multiplex; - -import org.apache.log4j.Appender; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.OptionHandler; - -/** - * @author psmith - * - */ -public interface MultiplexSelector extends OptionHandler{ - - public void setAppenderFactory(AppenderFactory factory); - - public Appender select(LoggingEvent e); - - /** - * - */ - public void close(); -} diff --git a/src/main/java/org/apache/log4j/multiplex/MultiplexSelectorSkeleton.java b/src/main/java/org/apache/log4j/multiplex/MultiplexSelectorSkeleton.java deleted file mode 100644 index bcee5d9355..0000000000 --- a/src/main/java/org/apache/log4j/multiplex/MultiplexSelectorSkeleton.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.apache.log4j.multiplex; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.apache.log4j.Appender; -import org.apache.log4j.spi.LoggingEvent; - -/** - * @author psmith - * - */ -public abstract class MultiplexSelectorSkeleton implements MultiplexSelector { - - private AppenderFactory appenderFactory; - - protected Map multiplexedAppenders = Collections - .synchronizedMap(new HashMap()); - - public void close() { - // TODO probable should log that we're closing each appender - for (Iterator iter = multiplexedAppenders.values().iterator(); iter - .hasNext();) { - Appender appender = (Appender) iter.next(); - appender.close(); - } - - } - - /** - * @return Returns the appenderFactory. - */ - public final AppenderFactory getAppenderFactory() { - return appenderFactory; - } - - /** - * @param appenderFactory - * The appenderFactory to set. - */ - public final void setAppenderFactory(AppenderFactory appenderFactory) { - this.appenderFactory = appenderFactory; - } - - protected Appender lookupOrCreateAsNeeded(Object key, LoggingEvent e) { - Appender appender = (Appender) multiplexedAppenders.get(key); - if (appender == null) { - appender = getAppenderFactory().create(e); - multiplexedAppenders.put(key, appender); - } - return appender; - - } - -} \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/net/AddressBased.java b/src/main/java/org/apache/log4j/net/AddressBased.java deleted file mode 100644 index ccd2e6a74d..0000000000 --- a/src/main/java/org/apache/log4j/net/AddressBased.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.net; - - -/** - * Net based entities that 'work with' an Address - * should consider implementing this - * interface so that they can be treated generically. - * - * @author Paul Smith (psmith@apache.org) - * - */ -public interface AddressBased extends NetworkBased { - /** - * Returns a String representation of the Address this instance - * encompasses. - * @return String representation of the Address - */ - String getAddress(); -} diff --git a/src/main/java/org/apache/log4j/net/JMSAppender.java b/src/main/java/org/apache/log4j/net/JMSAppender.java index 74c0486540..7e1e62ead5 100644 --- a/src/main/java/org/apache/log4j/net/JMSAppender.java +++ b/src/main/java/org/apache/log4j/net/JMSAppender.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -18,10 +18,11 @@ package org.apache.log4j.net; import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.spi.ErrorCode; import org.apache.log4j.spi.LoggingEvent; -import java.util.Properties; - +import javax.jms.JMSException; import javax.jms.ObjectMessage; import javax.jms.Session; import javax.jms.Topic; @@ -29,21 +30,20 @@ import javax.jms.TopicConnectionFactory; import javax.jms.TopicPublisher; import javax.jms.TopicSession; - import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NameNotFoundException; import javax.naming.NamingException; - +import java.util.Properties; /** * A simple appender that publishes events to a JMS Topic. The events * are serialized and transmitted as JMS message type {@link - * javax.jms.ObjectMessage}. + * ObjectMessage}. - *

    JMS {@link javax.jms.Topic topics} and {@link javax.jms.TopicConnectionFactory topic + *

    JMS {@link Topic topics} and {@link TopicConnectionFactory topic * connection factories} are administered objects that are retrieved - * using JNDI messaging which in turn requires the retreival of a JNDI + * using JNDI messaging which in turn requires the retrieval of a JNDI * {@link Context}. *

    There are two common methods for retrieving a JNDI {@link @@ -55,15 +55,15 @@

        InitialContext jndiContext = new InitialContext();
        
    - + *

    Calling the no-argument InitialContext() method * will also work from within Enterprise Java Beans (EJBs) because it * is part of the EJB contract for application servers to provide each * bean an environment naming context (ENC). - + *

    In the second approach, several predetermined properties are set * and these properties are passed to the InitialContext - * contructor to connect to the naming service provider. For example, + * constructor to connect to the naming service provider. For example, * to connect to JBoss naming service one would write:

    @@ -74,7 +74,7 @@
        InitialContext jndiContext = new InitialContext(env);
     
    - * where hostname is the host where the JBoss applicaiton + * where hostname is the host where the JBoss application * server is running. * *

    To connect to the the naming service of Weblogic application @@ -88,7 +88,7 @@

    *

    Other JMS providers will obviously require different values. - * + * * The initial JNDI context can be obtained by calling the * no-argument InitialContext() method in EJBs. Only * clients running in a separate JVM need to be concerned about the @@ -100,9 +100,7 @@ @author Ceki Gülcü */ public class JMSAppender extends AppenderSkeleton { - - static int SUCCESSIVE_FAILURE_LIMIT = 3; - + String securityPrincipalName; String securityCredentials; String initialContextFactoryName; @@ -113,15 +111,13 @@ public class JMSAppender extends AppenderSkeleton { String userName; String password; boolean locationInfo; - TopicConnection topicConnection; + + TopicConnection topicConnection; TopicSession topicSession; - TopicPublisher topicPublisher; + TopicPublisher topicPublisher; - boolean inOrder = false; - int successiveFailureCount = 0; - - public JMSAppender() { - super(false); + public + JMSAppender() { } /** @@ -129,14 +125,16 @@ public JMSAppender() { string value. Its value will be used to lookup the appropriate TopicConnectionFactory from the JNDI context. */ - public void setTopicConnectionFactoryBindingName(String tcfBindingName) { + public + void setTopicConnectionFactoryBindingName(String tcfBindingName) { this.tcfBindingName = tcfBindingName; } /** Returns the value of the TopicConnectionFactoryBindingName option. */ - public String getTopicConnectionFactoryBindingName() { + public + String getTopicConnectionFactoryBindingName() { return tcfBindingName; } @@ -145,22 +143,26 @@ public String getTopicConnectionFactoryBindingName() { string value. Its value will be used to lookup the appropriate Topic from the JNDI context. */ - public void setTopicBindingName(String topicBindingName) { + public + void setTopicBindingName(String topicBindingName) { this.topicBindingName = topicBindingName; } /** Returns the value of the TopicBindingName option. */ - public String getTopicBindingName() { + public + String getTopicBindingName() { return topicBindingName; } + /** - * Returns value of the LocationInfo property which determines whether - * caller's location info is sent to the remote subscriber. - * */ - public boolean getLocationInfo() { + Returns value of the LocationInfo property which + determines whether location (stack) info is sent to the remote + subscriber. */ + public + boolean getLocationInfo() { return locationInfo; } @@ -168,156 +170,156 @@ public boolean getLocationInfo() { * Options are activated and become effective only after calling * this method.*/ public void activateOptions() { - TopicConnectionFactory topicConnectionFactory; + TopicConnectionFactory topicConnectionFactory; try { Context jndi; - getLogger().debug("Getting initial context."); - if (initialContextFactoryName != null) { - Properties env = new Properties(); - env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactoryName); - if (providerURL != null) { - env.put(Context.PROVIDER_URL, providerURL); - } else { - getLogger().warn( - "You have set InitialContextFactoryName option but not the " - + "ProviderURL. This is likely to cause problems."); - } - if (urlPkgPrefixes != null) { - env.put(Context.URL_PKG_PREFIXES, urlPkgPrefixes); - } - - if (securityPrincipalName != null) { - env.put(Context.SECURITY_PRINCIPAL, securityPrincipalName); - if (securityCredentials != null) { - env.put(Context.SECURITY_CREDENTIALS, securityCredentials); - } else { - getLogger().warn( - "You have set SecurityPrincipalName option but not the " - + "SecurityCredentials. This is likely to cause problems."); - } - } - jndi = new InitialContext(env); + LogLog.debug("Getting initial context."); + if(initialContextFactoryName != null) { + Properties env = new Properties( ); + env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactoryName); + if(providerURL != null) { + env.put(Context.PROVIDER_URL, providerURL); + } else { + LogLog.warn("You have set InitialContextFactoryName option but not the " + +"ProviderURL. This is likely to cause problems."); + } + if(urlPkgPrefixes != null) { + env.put(Context.URL_PKG_PREFIXES, urlPkgPrefixes); + } + + if(securityPrincipalName != null) { + env.put(Context.SECURITY_PRINCIPAL, securityPrincipalName); + if(securityCredentials != null) { + env.put(Context.SECURITY_CREDENTIALS, securityCredentials); + } else { + LogLog.warn("You have set SecurityPrincipalName option but not the " + +"SecurityCredentials. This is likely to cause problems."); + } + } + jndi = new InitialContext(env); } else { - jndi = new InitialContext(); + jndi = new InitialContext(); } - getLogger().debug("Looking up [{}]", tcfBindingName); - topicConnectionFactory = - (TopicConnectionFactory) lookup(jndi, tcfBindingName); - getLogger().debug("About to create TopicConnection."); - if (userName != null) { - this.topicConnection = - topicConnectionFactory.createTopicConnection(userName, password); + LogLog.debug("Looking up ["+tcfBindingName+"]"); + topicConnectionFactory = (TopicConnectionFactory) lookup(jndi, tcfBindingName); + LogLog.debug("About to create TopicConnection."); + if(userName != null) { + topicConnection = topicConnectionFactory.createTopicConnection(userName, + password); } else { - this.topicConnection = topicConnectionFactory.createTopicConnection(); + topicConnection = topicConnectionFactory.createTopicConnection(); } - getLogger().debug( - "Creating TopicSession, non-transactional, " - + "in AUTO_ACKNOWLEDGE mode."); - this.topicSession = - topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); + LogLog.debug("Creating TopicSession, non-transactional, " + +"in AUTO_ACKNOWLEDGE mode."); + topicSession = topicConnection.createTopicSession(false, + Session.AUTO_ACKNOWLEDGE); - getLogger().debug("Looking up topic name [" + topicBindingName + "]."); + LogLog.debug("Looking up topic name ["+topicBindingName+"]."); Topic topic = (Topic) lookup(jndi, topicBindingName); - getLogger().debug("Creating TopicPublisher."); - this.topicPublisher = topicSession.createPublisher(topic); - - getLogger().debug("Starting TopicConnection."); + LogLog.debug("Creating TopicPublisher."); + topicPublisher = topicSession.createPublisher(topic); + + LogLog.debug("Starting TopicConnection."); topicConnection.start(); jndi.close(); - } catch (Exception e) { - getLogger().error( - "Error while activating options for appender named [" + name + "].", e); - } - - - if (this.topicConnection != null && this.topicSession != null && this.topicPublisher != null) { - inOrder = true; - } else { - inOrder = false; - } - if(inOrder) { - super.activateOptions(); + } catch(JMSException e) { + errorHandler.error("Error while activating options for appender named ["+name+ + "].", e, ErrorCode.GENERIC_FAILURE); + } catch(NamingException e) { + errorHandler.error("Error while activating options for appender named ["+name+ + "].", e, ErrorCode.GENERIC_FAILURE); + } catch(RuntimeException e) { + errorHandler.error("Error while activating options for appender named ["+name+ + "].", e, ErrorCode.GENERIC_FAILURE); } } protected Object lookup(Context ctx, String name) throws NamingException { try { return ctx.lookup(name); - } catch (NameNotFoundException e) { - getLogger().error("Could not find name [" + name + "]."); + } catch(NameNotFoundException e) { + LogLog.error("Could not find name ["+name+"]."); throw e; } } + protected boolean checkEntryConditions() { + String fail = null; + + if(this.topicConnection == null) { + fail = "No TopicConnection"; + } else if(this.topicSession == null) { + fail = "No TopicSession"; + } else if(this.topicPublisher == null) { + fail = "No TopicPublisher"; + } + + if(fail != null) { + errorHandler.error(fail +" for JMSAppender named ["+name+"]."); + return false; + } else { + return true; + } + } + /** Close this JMSAppender. Closing releases all resources used by the appender. A closed appender cannot be re-opened. */ public synchronized void close() { // The synchronized modifier avoids concurrent append and close operations - if (this.closed) { - return; + + if(this.closed) { + return; } - getLogger().debug("Closing appender [" + name + "]."); + LogLog.debug("Closing appender ["+name+"]."); this.closed = true; try { - if (topicSession != null) { + if(topicSession != null) { topicSession.close(); - } - if (topicConnection != null) { + } + if(topicConnection != null) { topicConnection.close(); - } - } catch (Exception e) { - getLogger().error("Error while closing JMSAppender [" + name + "].", e); } - + } catch(JMSException e) { + LogLog.error("Error while closing JMSAppender ["+name+"].", e); + } catch(RuntimeException e) { + LogLog.error("Error while closing JMSAppender ["+name+"].", e); + } // Help garbage collection topicPublisher = null; topicSession = null; topicConnection = null; } - /** - * Gets whether appender is properly configured to append messages. - * @return true if properly configured. - */ - protected boolean checkEntryConditions() { - return inOrder; - } - - /** This method called by {@link AppenderSkeleton#doAppend} method to do most of the real appending work. */ public void append(LoggingEvent event) { - if (!checkEntryConditions()) { + if(!checkEntryConditions()) { return; } try { ObjectMessage msg = topicSession.createObjectMessage(); - if (locationInfo) { - event.getLocationInformation(); + if(locationInfo) { + event.getLocationInformation(); } msg.setObject(event); topicPublisher.publish(msg); - successiveFailureCount = 0; - } catch (Exception e) { - successiveFailureCount++; - if(successiveFailureCount > SUCCESSIVE_FAILURE_LIMIT) { - inOrder = false; - } - getLogger().error( - "Could not publish message in JMSAppender [" + name + "].", e); - - + } catch(JMSException e) { + errorHandler.error("Could not publish message in JMSAppender ["+name+"].", e, + ErrorCode.GENERIC_FAILURE); + } catch(RuntimeException e) { + errorHandler.error("Could not publish message in JMSAppender ["+name+"].", e, + ErrorCode.GENERIC_FAILURE); } } @@ -327,48 +329,49 @@ public void append(LoggingEvent event) { * meaning of this option. * */ public String getInitialContextFactoryName() { - return initialContextFactoryName; + return initialContextFactoryName; } - + /** * Setting the InitialContextFactoryName method will cause * this JMSAppender instance to use the {@link * InitialContext#InitialContext(Hashtable)} method instead of the * no-argument constructor. If you set this option, you should also * at least set the ProviderURL option. - * - *

    See also {@link #setProviderURL(String)}. + * + * @see #setProviderURL(String) * */ public void setInitialContextFactoryName(String initialContextFactoryName) { this.initialContextFactoryName = initialContextFactoryName; } public String getProviderURL() { - return providerURL; + return providerURL; } public void setProviderURL(String providerURL) { this.providerURL = providerURL; } - String getURLPkgPrefixes() { + String getURLPkgPrefixes( ) { return urlPkgPrefixes; } - public void setURLPkgPrefixes(String urlPkgPrefixes) { + public void setURLPkgPrefixes(String urlPkgPrefixes ) { this.urlPkgPrefixes = urlPkgPrefixes; } - + public String getSecurityCredentials() { - return securityCredentials; + return securityCredentials; } public void setSecurityCredentials(String securityCredentials) { this.securityCredentials = securityCredentials; } - + + public String getSecurityPrincipalName() { - return securityPrincipalName; + return securityPrincipalName; } public void setSecurityPrincipalName(String securityPrincipalName) { @@ -376,12 +379,12 @@ public void setSecurityPrincipalName(String securityPrincipalName) { } public String getUserName() { - return userName; + return userName; } /** * The user name to use when {@link - * javax.jms.TopicConnectionFactory#createTopicConnection(String, String)} + * TopicConnectionFactory#createTopicConnection(String, String) * creating a topic session}. If you set this option, you should * also set the Password option. See {@link * #setPassword(String)}. @@ -391,21 +394,21 @@ public void setUserName(String userName) { } public String getPassword() { - return password; + return password; } /** - * The paswword to use when creating a topic session. + * The paswword to use when creating a topic session. */ public void setPassword(String password) { this.password = password; } + /** - * If true, the information sent to the remote subscriber will include - * caller's location information. Due to performance concerns, by default no - * location information is sent to the subscriber. - * */ + If true, the information sent to the remote subscriber will + include caller's location information. By default no location + information is sent to the subscriber. */ public void setLocationInfo(boolean locationInfo) { this.locationInfo = locationInfo; } @@ -433,13 +436,12 @@ protected TopicSession getTopicSession() { protected TopicPublisher getTopicPublisher() { return topicPublisher; } - - /** - * Gets whether appender requires a layout. - * @return false - */ + + /** + * The JMSAppender sends serialized events and consequently does not + * require a layout. + */ public boolean requiresLayout() { - return false; + return false; } - } diff --git a/src/main/java/org/apache/log4j/net/JMSReceiver.java b/src/main/java/org/apache/log4j/net/JMSReceiver.java deleted file mode 100644 index b26541a651..0000000000 --- a/src/main/java/org/apache/log4j/net/JMSReceiver.java +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.net; - -import java.io.FileInputStream; -import java.util.Properties; - -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.TopicConnection; -import javax.jms.Topic; -import javax.jms.TopicConnectionFactory; -import javax.jms.TopicSubscriber; -import javax.jms.Session; -import javax.jms.TopicSession; -import javax.jms.ObjectMessage; - -import javax.naming.InitialContext; -import javax.naming.Context; -import javax.naming.NameNotFoundException; -import javax.naming.NamingException; - -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.plugins.Plugin; -import org.apache.log4j.plugins.Receiver; - -/** - JMSReceiver receives a remote logging event on a configured - JSM topic and "posts" it to a LoggerRepository as if the event was - generated locally. This class is designed to receive events from - the JMSAppender class (or classes that send compatible events). - -

    Once the event has been "posted", it will be handled by the - appenders currently configured in the LoggerRespository. - -

    This implementation borrows heavily from the JMSSink - implementation. - - @author Mark Womack - @author Paul Smith - @author Stephen Pain - @since 1.3 -*/ -public class JMSReceiver extends Receiver implements MessageListener { - - private boolean active = false; - - protected String topicFactoryName; - protected String topicName; - protected String userId; - protected String password; - protected TopicConnection topicConnection; - protected String jndiPath; - - private String remoteInfo; - private String providerUrl; - - public JMSReceiver() { } - - public JMSReceiver(String _topicFactoryName, String _topicName, - String _userId, String _password, String _jndiPath) { - topicFactoryName = _topicFactoryName; - topicName = _topicName; - userId = _userId; - password = _password; - jndiPath = _jndiPath; - } - - /** - * Sets the path to a properties file containing - * the initial context and jndi provider url - */ - public void setJndiPath(String _jndiPath) { - jndiPath = _jndiPath; - } - - /** - * Gets the path to a properties file containing - * the initial context and jndi provider url - */ - public String getJndiPath() { - return jndiPath; - } - - /** - Sets the JMS topic factory name to use when creating the - JMS connection. */ - public void setTopicFactoryName(String _topicFactoryName) { - topicFactoryName = _topicFactoryName; - } - - /** - Gets the curernt JMS topic factory name property. */ - public String getTopicFactoryName() { - return topicFactoryName; - } - - /** - * Sets the JMS topic name to use when creating the - * JMS connection. - */ - public void setTopicName(String _topicName) { - topicName = _topicName; - } - - /** - * Gets the curernt JMS topic name property. - */ - public String getTopicName() { - return topicName; - } - - /** - Sets the user id to use when creating the - JMS connection. */ - public void setUserId(String _userId) { - userId = _userId; - } - - /** - * Gets the current user id property. - */ - public String getUserId() { - return userId; - } - - /** - * Sets the password to use when creating the - * JMS connection. - */ - public void setPassword(String _password) { - password = _password; - } - - /** - * Gets the curernt password property. - */ - public String getPassword() { - return password; - } - - /** - * Returns true if the receiver is the same class and they are - * configured for the same properties, and super class also considers - * them to be equivalent. This is used by PluginRegistry when determining - * if the a similarly configured receiver is being started. - * - * @param testPlugin The plugin to test equivalency against. - * @return boolean True if the testPlugin is equivalent to this plugin. - */ - public boolean isEquivalent(Plugin testPlugin) { - // only do full check if an instance of this class - if (testPlugin instanceof JMSReceiver) { - - JMSReceiver receiver = (JMSReceiver)testPlugin; - - // check for same topic name and super class equivalency - return ( - topicFactoryName.equals(receiver.getTopicFactoryName()) && - (jndiPath == null || jndiPath.equals(receiver.getJndiPath())) && - super.isEquivalent(testPlugin) - ); - } - - return false; - } - - /** - Returns true if this receiver is active. */ - public synchronized boolean isActive() { - return active; - } - - /** - Sets the flag to indicate if receiver is active or not. */ - protected synchronized void setActive(boolean _active) { - active = _active; - } - - /** - Starts the JMSReceiver with the current options. */ - public void activateOptions() { - if (!isActive()) { - try { - remoteInfo = topicFactoryName + ":" + topicName; - - Context ctx = null; - if (jndiPath == null || jndiPath.equals("")) { - ctx = new InitialContext(); - } else { - FileInputStream is = new FileInputStream(jndiPath); - Properties p = new Properties(); - p.load(is); - is.close(); - ctx = new InitialContext(p); - } - - // give some more flexibility about the choice of a tab name - providerUrl = (String)ctx.getEnvironment().get(Context.PROVIDER_URL); - TopicConnectionFactory topicConnectionFactory; - topicConnectionFactory = - (TopicConnectionFactory) lookup(ctx, topicFactoryName); - - if (userId != null && password != null) { - topicConnection = - topicConnectionFactory.createTopicConnection(userId, password); - } else { - topicConnection = - topicConnectionFactory.createTopicConnection(); - } - - TopicSession topicSession = - topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - - Topic topic = (Topic)ctx.lookup(topicName); - - TopicSubscriber topicSubscriber = topicSession.createSubscriber(topic); - - topicSubscriber.setMessageListener(this); - - topicConnection.start(); - - setActive(true); - } catch(Exception e) { - setActive(false); - if (topicConnection != null) { - try { - topicConnection.close(); - } catch (Exception e2) { - // do nothing - } - topicConnection = null; - } - getLogger().error("Could not start JMSReceiver.", e); - } - } - } - - /** - Called when the receiver should be stopped. */ - public synchronized void shutdown() { - if (isActive()) { - // mark this as no longer running - setActive(false); - - if (topicConnection != null) { - try { - topicConnection.close(); - } catch (Exception e) { - // do nothing - } - topicConnection = null; - } - } - } - - public void onMessage(Message message) { - try { - if(message instanceof ObjectMessage) { - // get the logging event and post it to the repository - ObjectMessage objectMessage = (ObjectMessage) message; - LoggingEvent event = (LoggingEvent) objectMessage.getObject(); - - // store the known remote info in an event property - event.setProperty("log4j.remoteSourceInfo", remoteInfo); - event.setProperty("log4j.jmsProviderUrl", providerUrl); - - doPost(event); - } else { - getLogger().warn("Received message is of type "+message.getJMSType() - +", was expecting ObjectMessage."); - } - } catch(Exception e) { - getLogger().error("Exception thrown while processing incoming message.", e); - } - } - - protected Object lookup(Context ctx, String name) throws NamingException { - try { - return ctx.lookup(name); - } catch(NameNotFoundException e) { - getLogger().error("Could not find name ["+name+"]."); - throw e; - } - } - -} diff --git a/src/main/java/org/apache/log4j/net/JMSReceiverBeanInfo.java b/src/main/java/org/apache/log4j/net/JMSReceiverBeanInfo.java deleted file mode 100644 index eec19d3e74..0000000000 --- a/src/main/java/org/apache/log4j/net/JMSReceiverBeanInfo.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.net; - -import java.beans.PropertyDescriptor; -import java.beans.SimpleBeanInfo; - - -/** - * BeanInfo class for the JMSReceiver. - * - * @author Paul Smith - * - */ -public class JMSReceiverBeanInfo extends SimpleBeanInfo { - - /* (non-Javadoc) - * @see java.beans.BeanInfo#getPropertyDescriptors() - */ - public PropertyDescriptor[] getPropertyDescriptors() { - - try { - - return new PropertyDescriptor[] { - new PropertyDescriptor("name", JMSReceiver.class), - new PropertyDescriptor("topicFactoryName", JMSReceiver.class), - new PropertyDescriptor("topicName", JMSReceiver.class), - new PropertyDescriptor("threshold", JMSReceiver.class), - new PropertyDescriptor("jndiPath", JMSReceiver.class), - new PropertyDescriptor("userId", - JMSReceiver.class), - }; - } catch (Exception e) { - } - - return null; - } -} diff --git a/src/main/java/org/apache/log4j/net/JMSSink.java b/src/main/java/org/apache/log4j/net/JMSSink.java index f97880aea5..6a02831e1a 100644 --- a/src/main/java/org/apache/log4j/net/JMSSink.java +++ b/src/main/java/org/apache/log4j/net/JMSSink.java @@ -17,31 +17,25 @@ package org.apache.log4j.net; -import org.apache.log4j.joran.JoranConfigurator; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.xml.DOMConfigurator; - - -import javax.jms.TopicConnection; +import javax.jms.JMSException; +import javax.jms.ObjectMessage; +import javax.jms.Session; import javax.jms.Topic; +import javax.jms.TopicConnection; import javax.jms.TopicConnectionFactory; -import javax.jms.TopicSubscriber; -import javax.jms.Session; import javax.jms.TopicSession; -import javax.jms.ObjectMessage; -import javax.jms.JMSException; - -import java.io.BufferedReader; -import java.io.InputStreamReader; - -import javax.naming.InitialContext; +import javax.jms.TopicSubscriber; import javax.naming.Context; +import javax.naming.InitialContext; import javax.naming.NameNotFoundException; import javax.naming.NamingException; +import java.io.BufferedReader; +import java.io.InputStreamReader; /** * A simple application that consumes logging events sent by a {@link @@ -68,9 +62,7 @@ static public void main(String[] args) throws Exception { String configFile = args[4]; if(configFile.endsWith(".xml")) { - JoranConfigurator jc = new JoranConfigurator(); - LoggerRepository repository = LogManager.getLoggerRepository(); - jc.doConfigure(configFile, repository); + DOMConfigurator.configure(configFile); } else { PropertyConfigurator.configure(configFile); } @@ -78,14 +70,14 @@ static public void main(String[] args) throws Exception { new JMSSink(tcfBindingName, topicBindingName, username, password); BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); - // Loop until the word "exit" is typed or EOF + // Loop until the word "exit" is typed System.out.println("Type \"exit\" to quit JMSSink."); while(true){ - String s = stdin.readLine(); - if (s == null || s.equalsIgnoreCase("exit")) { - System.out.println("Exiting. Kill the application if it does not exit " - + "due to daemon threads."); - return; + String s = stdin.readLine( ); + if (s.equalsIgnoreCase("exit")) { + System.out.println("Exiting. Kill the application if it does not exit " + + "due to daemon threads."); + return; } } } @@ -113,7 +105,11 @@ public JMSSink( String tcfBindingName, String topicBindingName, String username, topicSubscriber.setMessageListener(this); - } catch(Exception e) { + } catch(JMSException e) { + logger.error("Could not read JMS message.", e); + } catch(NamingException e) { + logger.error("Could not read JMS message.", e); + } catch(RuntimeException e) { logger.error("Could not read JMS message.", e); } } diff --git a/src/main/java/org/apache/log4j/net/MulticastAppender.java b/src/main/java/org/apache/log4j/net/MulticastAppender.java deleted file mode 100644 index f858e85624..0000000000 --- a/src/main/java/org/apache/log4j/net/MulticastAppender.java +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.net; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.InetAddress; -import java.net.MulticastSocket; -import java.net.UnknownHostException; - -import org.apache.log4j.AppenderSkeleton; -import org.apache.log4j.helpers.Constants; -import org.apache.log4j.spi.LoggingEvent; - - -/** - * Multicast-based Appender. Works in conjunction with the MulticastReceiver, which expects - * a LoggingEvent encoded using XMLLayout. - * - * Sends log information as a multicast datagrams. - * - *

    Messages are not sent as LoggingEvent objects but as text after - * applying XMLLayout. - * - *

    The port and remoteHost properties can be set in configuration properties. - * By setting the remoteHost to a broadcast address any number of clients can - * listen for log messages. - * - *

    This was inspired and really extended/copied from {@link SocketAppender}. Please - * see the docs for the proper credit to the authors of that class. - * - * @author Kevin Brown - * @author Scott Deboy - * - */ -public class MulticastAppender extends AppenderSkeleton implements PortBased { - /** - The default port number for the multicast packets. (9991). - */ - static final int DEFAULT_PORT = 9991; - - /** - We remember host name as String in addition to the resolved - InetAddress so that it can be returned via getOption(). - */ - String hostname; - String remoteHost; - String application; - String overrideProperties = "true"; - int timeToLive; - InetAddress address; - int port = DEFAULT_PORT; - MulticastSocket outSocket; - private String encoding; - - public MulticastAppender() { - super(false); - } - - /** - Open the multicast sender for the RemoteHost and Port. - */ - public void activateOptions() { - try { - hostname = InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException uhe) { - try { - hostname = InetAddress.getLocalHost().getHostAddress(); - } catch (UnknownHostException uhe2) { - hostname = "unknown"; - } - } - - //allow system property of application to be primary - if (application == null) { - application = System.getProperty(Constants.APPLICATION_KEY); - } else { - if (System.getProperty(Constants.APPLICATION_KEY) != null) { - application = application + "-" + System.getProperty(Constants.APPLICATION_KEY); - } - } - - if(remoteHost != null) { - address = getAddressByName(remoteHost); - } else { - String err = "The RemoteHost property is required for SocketAppender named "+ name; - getLogger().error(err); - throw new IllegalStateException(err); - } - - connect(); - super.activateOptions(); - } - - /** - Close this appender. -

    This will mark the appender as closed and - call then {@link #cleanUp} method. - */ - public synchronized void close() { - if (closed) { - return; - } - - this.closed = true; - cleanUp(); - } - - /** - Close the Socket and release the underlying - connector thread if it has been created - */ - public void cleanUp() { - if (outSocket != null) { - try { - outSocket.close(); - } catch (Exception e) { - getLogger().error("Could not close outSocket.", e); - } - - outSocket = null; - } - } - - void connect() { - if (this.address == null) { - return; - } - - try { - // First, close the previous connection if any. - cleanUp(); - outSocket = new MulticastSocket(); - outSocket.setTimeToLive(timeToLive); - } catch (IOException e) { - getLogger().error("Error in connect method of MulticastAppender named "+name, e); - } - } - - public void append(LoggingEvent event) { - if (event == null) { - return; - } - - if (outSocket != null) { - //if the values already exist, don't set (useful when forwarding from a simplesocketserver - if ( - (overrideProperties != null) - && overrideProperties.equalsIgnoreCase("true")) { - event.setProperty(Constants.HOSTNAME_KEY, hostname); - - if (application != null) { - event.setProperty(Constants.APPLICATION_KEY, application); - } - } - - try { - StringBuffer buf = new StringBuffer(layout.format(event)); - - byte[] payload; - if(encoding == null) { - payload = buf.toString().getBytes(); - } else { - payload = buf.toString().getBytes(encoding); - } - - DatagramPacket dp = - new DatagramPacket(payload, payload.length, address, port); - outSocket.send(dp); - //remove these properties, in case other appenders need to set them to different values - event.setProperty(Constants.HOSTNAME_KEY, null); - event.setProperty(Constants.APPLICATION_KEY, null); - } catch (IOException e) { - outSocket = null; - getLogger().warn("Detected problem with Multicast connection: " + e); - } - } - } - - InetAddress getAddressByName(String host) { - try { - return InetAddress.getByName(host); - } catch (Exception e) { - getLogger().error("Could not find address of [" + host + "].", e); - return null; - } - } - - /** - The RemoteHost option takes a string value which should be - the host name or ipaddress to send the multicast packets. - */ - public void setRemoteHost(String host) { - remoteHost = host; - } - - /** - Returns value of the RemoteHost option. - */ - public String getRemoteHost() { - return remoteHost; - } - - /** - The Encoding option specifies how the bytes are encoded. If this option is not specified, - the System encoding is used. - */ - public void setEncoding(String encoding) { - this.encoding = encoding; - } - - /** - Returns value of the Encoding option. - */ - public String getEncoding() { - return encoding; - } - /** - The App option takes a string value which should be the name of the application getting logged. - If property was already set (via system property), don't set here. - */ - public void setApplication(String app) { - this.application = app; - } - - /** - Returns value of the App option. - */ - public String getApplication() { - return application; - } - - /** - The OverrideProperties option allows configurations where the appender does not apply - the machinename/appname properties - the properties will be used as provided. - */ - public void setOverrideProperties(String overrideProperties) { - this.overrideProperties = overrideProperties; - } - - /** - Returns value of the OverrideProperties option. - */ - public String getOverrideProperties() { - return overrideProperties; - } - - /** - The Time to live option takes a positive integer representing - the time to live value. - */ - public void setTimeToLive(int timeToLive) { - this.timeToLive = timeToLive; - } - - /** - Returns value of the Time to Live option. - */ - public int getTimeToLive() { - return timeToLive; - } - - /** - The Port option takes a positive integer representing - the port where multicast packets will be sent. - */ - public void setPort(int port) { - this.port = port; - } - - /** - Returns value of the Port option. - */ - public int getPort() { - return port; - } - - /* (non-Javadoc) - * @see org.apache.log4j.net.NetworkBased#isActive() - */ - public boolean isActive() { - // TODO handle active/inactive - return true; - } - - /** - * Gets whether appender requires a layout. - * @return false - */ - public boolean requiresLayout() { - return true; - } - -} diff --git a/src/main/java/org/apache/log4j/net/MulticastReceiver.java b/src/main/java/org/apache/log4j/net/MulticastReceiver.java deleted file mode 100644 index 4788b03626..0000000000 --- a/src/main/java/org/apache/log4j/net/MulticastReceiver.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.net; - -import org.apache.log4j.plugins.Pauseable; -import org.apache.log4j.plugins.Receiver; -import org.apache.log4j.spi.Decoder; -import org.apache.log4j.spi.LoggingEvent; - -import java.io.IOException; - -import java.net.DatagramPacket; -import java.net.InetAddress; -import java.net.MulticastSocket; -import java.net.SocketException; -import java.net.UnknownHostException; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - - -/** - * Multicast-based receiver. Accepts LoggingEvents encoded using - * MulticastAppender and XMLLayout. The the XML data is converted - * back to a LoggingEvent and is posted. - * - * @author Scott Deboy - * - */ -public class MulticastReceiver extends Receiver implements PortBased, - AddressBased, Pauseable { - private static final int PACKET_LENGTH = 16384; - private boolean isActive = false; - private int port; - private String address; - private String encoding; - private MulticastSocket socket = null; - - //default to log4j xml decoder - private String decoder = "org.apache.log4j.xml.XMLDecoder"; - private Decoder decoderImpl; - private MulticastHandlerThread handlerThread; - private MulticastReceiverThread receiverThread; - private boolean paused; - - public String getDecoder() { - return decoder; - } - - public void setDecoder(String decoder) { - this.decoder = decoder; - } - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - public String getAddress() { - return address; - } - - /** - The Encoding option specifies how the bytes are encoded. If this option is not specified, - the system encoding will be used. - */ - public void setEncoding(String encoding) { - this.encoding = encoding; - } - - /** - Returns value of the Encoding option. - */ - public String getEncoding() { - return encoding; - } - - public synchronized void shutdown() { - isActive = false; - handlerThread.interrupt(); - receiverThread.interrupt(); - socket.close(); - } - - public void setAddress(String address) { - this.address = address; - } - - public boolean isPaused() { - return paused; - } - - public void setPaused(boolean b) { - paused = b; - } - - /** - Returns true if this receiver is active. */ - public synchronized boolean isActive() { - return isActive; - } - - public void activateOptions() { - InetAddress addr = null; - - try { - Class c = Class.forName(decoder); - Object o = c.newInstance(); - - if (o instanceof Decoder) { - this.decoderImpl = (Decoder) o; - } - } catch (ClassNotFoundException cnfe) { - getLogger().warn("Unable to find decoder", cnfe); - } catch (IllegalAccessException iae) { - getLogger().warn("Could not construct decoder", iae); - } catch (InstantiationException ie) { - getLogger().warn("Could not construct decoder", ie); - } - - try { - addr = InetAddress.getByName(address); - } catch (UnknownHostException uhe) { - uhe.printStackTrace(); - } - - try { - isActive = true; - socket = new MulticastSocket(port); - socket.joinGroup(addr); - receiverThread = new MulticastReceiverThread(); - receiverThread.start(); - handlerThread = new MulticastHandlerThread(); - handlerThread.start(); - } catch (IOException ioe) { - ioe.printStackTrace(); - } - } - - class MulticastHandlerThread extends Thread { - private List list = new ArrayList(); - - public MulticastHandlerThread() { - setDaemon(true); - } - - public void append(String data) { - synchronized (list) { - list.add(data); - list.notify(); - } - } - - public void run() { - ArrayList list2 = new ArrayList(); - - while (isAlive()) { - synchronized (list) { - try { - while (list.size() == 0) { - list.wait(); - } - - if (list.size() > 0) { - list2.addAll(list); - list.clear(); - } - } catch (InterruptedException ie) { - } - } - - if (list2.size() > 0) { - Iterator iter = list2.iterator(); - - while (iter.hasNext()) { - String data = (String) iter.next(); - List v = decoderImpl.decodeEvents(data.trim()); - - if (v != null) { - Iterator eventIter = v.iterator(); - - while (eventIter.hasNext()) { - if (!isPaused()) { - doPost((LoggingEvent) eventIter.next()); - } - } - } - } - - list2.clear(); - } else { - try { - synchronized (this) { - wait(1000); - } - } catch (InterruptedException ie) { - } - } - } - } - } - - class MulticastReceiverThread extends Thread { - public MulticastReceiverThread() { - setDaemon(true); - } - - public void run() { - isActive = true; - - byte[] b = new byte[PACKET_LENGTH]; - DatagramPacket p = new DatagramPacket(b, b.length); - - while (isActive) { - try { - socket.receive(p); - - //this string constructor which accepts a charset throws an exception if it is - //null - if (encoding == null) { - handlerThread.append( - new String(p.getData(), 0, p.getLength())); - } else { - handlerThread.append( - new String(p.getData(), 0, p.getLength(), encoding)); - } - } catch (SocketException se) { - //disconnected - } catch (IOException ioe) { - ioe.printStackTrace(); - } - } - - getLogger().debug("{}'s thread is ending.", MulticastReceiver.this.getName()); - } - } -} diff --git a/src/main/java/org/apache/log4j/net/MulticastReceiverBeanInfo.java b/src/main/java/org/apache/log4j/net/MulticastReceiverBeanInfo.java deleted file mode 100644 index 32ff8df690..0000000000 --- a/src/main/java/org/apache/log4j/net/MulticastReceiverBeanInfo.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.net; - -import java.beans.PropertyDescriptor; -import java.beans.SimpleBeanInfo; - - -/** - * BeanInfo class for the meta-data of the MulticastReceiver. - * - * @author Paul Smith - * - */ -public class MulticastReceiverBeanInfo extends SimpleBeanInfo { - - /* (non-Javadoc) - * @see java.beans.BeanInfo#getPropertyDescriptors() - */ - public PropertyDescriptor[] getPropertyDescriptors() { - - try { - - return new PropertyDescriptor[] { - new PropertyDescriptor("name", MulticastReceiver.class), - new PropertyDescriptor("address", MulticastReceiver.class), - new PropertyDescriptor("port", MulticastReceiver.class), - new PropertyDescriptor("threshold", MulticastReceiver.class), - new PropertyDescriptor("decoder", MulticastReceiver.class), - }; - } catch (Exception e) { - } - - return null; - } -} diff --git a/src/main/java/org/apache/log4j/net/NetworkBased.java b/src/main/java/org/apache/log4j/net/NetworkBased.java deleted file mode 100644 index 9c5153fc2f..0000000000 --- a/src/main/java/org/apache/log4j/net/NetworkBased.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.net; - -/** - * The parent of all the Network based interfaces. - * - * @author Paul Smith (psmith@apache.org) - * - */ -public interface NetworkBased { - - /** - * Get name. - * @return name. - */ - String getName(); - - /** - * Get if item is active. - * @return if true, item is active. - */ - boolean isActive(); -} diff --git a/src/main/java/org/apache/log4j/net/PortBased.java b/src/main/java/org/apache/log4j/net/PortBased.java deleted file mode 100644 index c7c1f97a3b..0000000000 --- a/src/main/java/org/apache/log4j/net/PortBased.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.net; - - -/** - * Net based entities that 'work with' a Port should consider implementing this - * interface so that they can be treated generically. - * - * @author Paul Smith (psmith@apache.org) - * - */ -public interface PortBased extends NetworkBased { - /** - * Returns the Port # that this net based thing is using. - * @return int port number - */ - int getPort(); -} diff --git a/src/main/java/org/apache/log4j/net/SMTPAppender.java b/src/main/java/org/apache/log4j/net/SMTPAppender.java index b9e79c1473..9162d07a53 100644 --- a/src/main/java/org/apache/log4j/net/SMTPAppender.java +++ b/src/main/java/org/apache/log4j/net/SMTPAppender.java @@ -17,38 +17,39 @@ package org.apache.log4j.net; -import java.util.Date; -import java.util.Properties; +import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.Layout; +import org.apache.log4j.Level; +import org.apache.log4j.helpers.CyclicBuffer; +import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.helpers.OptionConverter; +import org.apache.log4j.spi.ErrorCode; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.spi.OptionHandler; +import org.apache.log4j.spi.TriggeringEventEvaluator; +import org.apache.log4j.xml.UnrecognizedElementHandler; +import org.w3c.dom.Element; +import javax.mail.Authenticator; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart; -import javax.mail.Session; -import javax.mail.Authenticator; import javax.mail.PasswordAuthentication; +import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; +import javax.mail.internet.InternetHeaders; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NameNotFoundException; -import javax.naming.NamingException; - -import org.apache.log4j.AppenderSkeleton; -import org.apache.log4j.Layout; -import org.apache.log4j.Level; -import org.apache.log4j.PatternLayout; -import org.apache.log4j.helpers.CyclicBuffer; -import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.rule.ExpressionRule; -import org.apache.log4j.rule.Rule; -import org.apache.log4j.spi.ComponentBase; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.TriggeringEventEvaluator; - +import javax.mail.internet.MimeUtility; +import java.io.ByteArrayOutputStream; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.io.Writer; +import java.util.Date; +import java.util.Properties; /** Send an e-mail when a specific logging event occurs, typically on @@ -60,41 +61,23 @@ BufferSize logging events in its cyclic buffer. This keeps memory requirements at a reasonable level while still delivering useful application context. + + By default, an email message will be sent when an ERROR or higher + severity message is appended. The triggering criteria can be + modified by setting the evaluatorClass property with the name + of a class implementing TriggeringEventEvaluator, setting the evaluator + property with an instance of TriggeringEventEvaluator or + nesting a triggeringPolicy element where the specified + class implements TriggeringEventEvaluator. -

    There are three ways in which the trigger is fired, resulting in an email - containing the buffered events: - -

    * DEFAULT BEHAVIOR: relies on an internal TriggeringEventEvaluator class that - triggers the sending of an email when an event with a severity of ERROR or greater is received. -

    * Set the 'evaluatorClass' param to the fully qualified class name of a class you - have written that implements the TriggeringEventEvaluator interface. -

    * Set the 'expression' param to a valid (infix) expression supported by ExpressionRule and - ExpressionRule's supported operators and operands. - - As events are received, events are evaluated against the expression rule. An event - that causes the rule to evaluate to true triggers the email send. - - If both evaluatorClass and expression params are set, the evaluatorClass is used. - - See org.apache.log4j.rule.ExpressionRule for a more information. - -

    - The JavaMail session is obtained through {@link #setSessionJNDI(String) JNDI} or by - directly calling {@link Session#getDefaultInstance(Properties) and setting - various addressing details on this object. - The former method is preferred for application servers, - the latter for stand-alone usage. -

    - + This class has implemented UnrecognizedElementHandler since 1.2.15. + + Since 1.2.16, SMTP over SSL is supported by setting SMTPProtocol to "smpts". + @author Ceki Gülcü @since 1.0 */ -public class SMTPAppender extends AppenderSkeleton { - - /** - * JavaMail session. - */ - private Session session; - +public class SMTPAppender extends AppenderSkeleton + implements UnrecognizedElementHandler { private String to; /** * Comma separated list of cc recipients. @@ -103,144 +86,136 @@ public class SMTPAppender extends AppenderSkeleton { /** * Comma separated list of bcc recipients. */ - private String bcc; + private String bcc; private String from; - private String subjectStr = ""; + /** + * Comma separated list of replyTo addresses. + */ + private String replyTo; + private String subject; private String smtpHost; - private int smtpPort; private String smtpUsername; private String smtpPassword; - private String sessionJNDI; + private String smtpProtocol; + private int smtpPort = -1; private boolean smtpDebug = false; - private String charset = "ISO-8859-1"; private int bufferSize = 512; private boolean locationInfo = false; + private boolean sendOnClose = false; + protected CyclicBuffer cb = new CyclicBuffer(bufferSize); protected Message msg; + protected TriggeringEventEvaluator evaluator; - private PatternLayout subjectLayout; + + /** The default constructor will instantiate the appender with a {@link TriggeringEventEvaluator} that will trigger on events with level ERROR or higher.*/ - public SMTPAppender() { + public + SMTPAppender() { this(new DefaultEvaluator()); } + /** Use evaluator passed as parameter as the {@link TriggeringEventEvaluator} for this SMTPAppender. */ - public SMTPAppender(final TriggeringEventEvaluator evaluator) { - super(false); + public + SMTPAppender(TriggeringEventEvaluator evaluator) { this.evaluator = evaluator; } + /** Activate the specified options, such as the smtp host, the recipient, from, etc. */ - public void activateOptions() { - int errorCount = 0; - if (sessionJNDI != null) { - try { - session = lookupSession(); - if (session == null) - throw new NameNotFoundException(); - } catch (NamingException e) { - throw new IllegalStateException("Failed finding javax.mail.Session: " + sessionJNDI + " Reason: " + e); - } - } else { - session = createSession(); - } - + public + void activateOptions() { + Session session = createSession(); msg = new MimeMessage(session); - try { - addressMessage(msg); - } catch (MessagingException e) { - errorCount++; - getLogger().error("Could not activate SMTPAppender options.", e); - } - - if (subjectStr != null) { - subjectLayout = new PatternLayout(); - subjectLayout.setConversionPattern(subjectStr); - subjectLayout.setLoggerRepository(this.repository); - subjectLayout.activateOptions(); - } - if (this.evaluator == null) { - String errMsg = "No TriggeringEventEvaluator is set for appender ["+getName()+"]."; - getLogger().error(errMsg); - throw new IllegalStateException(errMsg); - } + try { + addressMessage(msg); + if(subject != null) { + try { + msg.setSubject(MimeUtility.encodeText(subject, "UTF-8", null)); + } catch(UnsupportedEncodingException ex) { + LogLog.error("Unable to encode SMTP subject", ex); + } + } + } catch(MessagingException e) { + LogLog.error("Could not activate SMTPAppender options.", e ); + } - if (this.layout == null) { - String errMsg = "No layout set for appender named [" + name + "]."; - getLogger().error(errMsg); - throw new IllegalStateException(errMsg); - } - - if (errorCount == 0) { - super.activateOptions(); - } + if (evaluator instanceof OptionHandler) { + ((OptionHandler) evaluator).activateOptions(); + } } - private Session lookupSession() throws NamingException { - Context c = new InitialContext(); - try { - return (Session) c.lookup(sessionJNDI); - } finally { - c.close(); - } - } - /** * Address message. * @param msg message, may not be null. * @throws MessagingException thrown if error addressing message. + * @since 1.2.14 */ protected void addressMessage(final Message msg) throws MessagingException { - if (from != null) { - msg.setFrom(getAddress(from)); - } else { - msg.setFrom(); - } - - if (to != null && to.length() > 0) { - msg.setRecipients(Message.RecipientType.TO, parseAddress(to)); - } - - //Add CC receipients if defined. - if (cc != null && cc.length() > 0) { - msg.setRecipients(Message.RecipientType.CC, parseAddress(cc)); - } - - //Add BCC receipients if defined. - if (bcc != null && bcc.length() > 0) { - msg.setRecipients(Message.RecipientType.BCC, parseAddress(bcc)); - } + if (from != null) { + msg.setFrom(getAddress(from)); + } else { + msg.setFrom(); + } + + //Add ReplyTo addresses if defined. + if (replyTo != null && replyTo.length() > 0) { + msg.setReplyTo(parseAddress(replyTo)); + } + + if (to != null && to.length() > 0) { + msg.setRecipients(Message.RecipientType.TO, parseAddress(to)); + } + + //Add CC receipients if defined. + if (cc != null && cc.length() > 0) { + msg.setRecipients(Message.RecipientType.CC, parseAddress(cc)); + } + + //Add BCC receipients if defined. + if (bcc != null && bcc.length() > 0) { + msg.setRecipients(Message.RecipientType.BCC, parseAddress(bcc)); + } } - + /** - * Returns a new mail session, using properties from the system. + * Create mail session. + * @return mail session, may not be null. + * @since 1.2.14 */ protected Session createSession() { - Properties props; + Properties props = null; try { props = new Properties (System.getProperties()); } catch(SecurityException ex) { props = new Properties(); } + + String prefix = "mail.smtp"; + if (smtpProtocol != null) { + props.put("mail.transport.protocol", smtpProtocol); + prefix = "mail." + smtpProtocol; + } if (smtpHost != null) { - props.put("mail.smtp.host", smtpHost); + props.put(prefix + ".host", smtpHost); } - if (smtpPort != 0) { - props.put("mail.smtp.port", String.valueOf(smtpPort)); + if (smtpPort > 0) { + props.put(prefix + ".port", String.valueOf(smtpPort)); } Authenticator auth = null; if(smtpPassword != null && smtpUsername != null) { - props.put("mail.smtp.auth", "true"); + props.put(prefix + ".auth", "true"); auth = new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(smtpUsername, smtpPassword); @@ -248,67 +223,83 @@ protected PasswordAuthentication getPasswordAuthentication() { }; } Session session = Session.getInstance(props, auth); + if (smtpProtocol != null) { + session.setProtocolForAddress("rfc822", smtpProtocol); + } if (smtpDebug) { session.setDebug(smtpDebug); } return session; } - /** Perform SMTPAppender specific appending actions, mainly adding the event to a cyclic buffer and checking if the event triggers an e-mail to be sent. */ - public void append(LoggingEvent event) { - if (!checkEntryConditions()) { + public + void append(LoggingEvent event) { + + if(!checkEntryConditions()) { return; } - event.prepareForDeferredProcessing(); - if (locationInfo) { + event.getThreadName(); + event.getNDC(); + event.getMDCCopy(); + if(locationInfo) { event.getLocationInformation(); } - + event.getRenderedMessage(); + event.getThrowableStrRep(); cb.add(event); - - if (evaluator.isTriggeringEvent(event)) { - sendBuffer(event); + if(evaluator.isTriggeringEvent(event)) { + sendBuffer(); } } - /** - This method determines if there is a sense in attempting to append. + /** + This method determines if there is a sense in attempting to append. -

    It checks whether there is a set output target and also if - there is a set layout. If these checks fail, then the boolean - value false is returned. */ - protected boolean checkEntryConditions() { - if (this.msg == null) { +

    It checks whether there is a set output target and also if + there is a set layout. If these checks fail, then the boolean + value false is returned. */ + protected + boolean checkEntryConditions() { + if(this.msg == null) { + errorHandler.error("Message object not configured."); return false; } - if (this.evaluator == null) { + if(this.evaluator == null) { + errorHandler.error("No TriggeringEventEvaluator is set for appender ["+ + name+"]."); return false; } - if (this.layout == null) { + + if(this.layout == null) { + errorHandler.error("No layout set for appender named ["+name+"]."); return false; } - return true; } - public synchronized void close() { + + synchronized + public + void close() { this.closed = true; + if (sendOnClose && cb.length() > 0) { + sendBuffer(); + } } InternetAddress getAddress(String addressStr) { try { return new InternetAddress(addressStr); - } catch (AddressException e) { - getLogger().error( - "Could not parse address [" + addressStr + "].", e); - + } catch(AddressException e) { + errorHandler.error("Could not parse address ["+addressStr+"].", e, + ErrorCode.ADDRESS_PARSE_FAILURE); return null; } } @@ -316,10 +307,9 @@ InternetAddress getAddress(String addressStr) { InternetAddress[] parseAddress(String addressStr) { try { return InternetAddress.parse(addressStr, true); - } catch (AddressException e) { - getLogger().error( - "Could not parse address [" + addressStr + "].", e); - + } catch(AddressException e) { + errorHandler.error("Could not parse address ["+addressStr+"].", e, + ErrorCode.ADDRESS_PARSE_FAILURE); return null; } } @@ -327,64 +317,97 @@ InternetAddress[] parseAddress(String addressStr) { /** Returns value of the To option. */ - public String getTo() { + public + String getTo() { return to; } + /** The SMTPAppender requires a {@link org.apache.log4j.Layout layout}. */ - public boolean requiresLayout() { + public + boolean requiresLayout() { return true; } /** - Send the contents of the cyclic buffer as an e-mail message. + * Layout body of email message. + * @since 1.2.16 */ - protected void sendBuffer(LoggingEvent triggeringEvent) { - // Note: this code already owns the monitor for this - // appender. This frees us from needing to synchronize on 'cb'. - try { - MimeBodyPart part = new MimeBodyPart(); - - if (msg instanceof MimeMessage) { - String computedSubject = computeSubject(triggeringEvent); - ((MimeMessage) msg).setSubject(computedSubject, charset); - } - + protected String formatBody() { + + // Note: this code already owns the monitor for this + // appender. This frees us from needing to synchronize on 'cb'. + StringBuffer sbuf = new StringBuffer(); String t = layout.getHeader(); - - if (t != null) { + if(t != null) { sbuf.append(t); + } + int len = cb.length(); + for(int i = 0; i < len; i++) { + //sbuf.append(MimeUtility.encodeText(layout.format(cb.get()))); + LoggingEvent event = cb.get(); + sbuf.append(layout.format(event)); + if(layout.ignoresThrowable()) { + String[] s = event.getThrowableStrRep(); + if (s != null) { + for(int j = 0; j < s.length; j++) { + sbuf.append(s[j]); + sbuf.append(Layout.LINE_SEP); + } + } + } } + t = layout.getFooter(); + if(t != null) { + sbuf.append(t); + } + + return sbuf.toString(); + } + + /** + Send the contents of the cyclic buffer as an e-mail message. + */ + protected + void sendBuffer() { - int len = cb.length(); - - for (int i = 0; i < len; i++) { - //sbuf.append(MimeUtility.encodeText(layout.format(cb.get()))); - LoggingEvent event = cb.get(); - sbuf.append(layout.format(event)); - - if (layout.ignoresThrowable()) { - String[] s = event.getThrowableStrRep(); - - if (s != null) { - for (int j = 0; j < s.length; j++) { - sbuf.append(s[j]); - sbuf.append(Layout.LINE_SEP); - } + try { + String s = formatBody(); + boolean allAscii = true; + for(int i = 0; i < s.length() && allAscii; i++) { + allAscii = s.charAt(i) <= 0x7F; + } + MimeBodyPart part; + if (allAscii) { + part = new MimeBodyPart(); + part.setContent(s, layout.getContentType()); + } else { + try { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + Writer writer = new OutputStreamWriter( + MimeUtility.encode(os, "quoted-printable"), "UTF-8"); + writer.write(s); + writer.close(); + InternetHeaders headers = new InternetHeaders(); + headers.setHeader("Content-Type", layout.getContentType() + "; charset=UTF-8"); + headers.setHeader("Content-Transfer-Encoding", "quoted-printable"); + part = new MimeBodyPart(headers, os.toByteArray()); + } catch(Exception ex) { + StringBuffer sbuf = new StringBuffer(s); + for (int i = 0; i < sbuf.length(); i++) { + if (sbuf.charAt(i) >= 0x80) { + sbuf.setCharAt(i, '?'); + } + } + part = new MimeBodyPart(); + part.setContent(sbuf.toString(), layout.getContentType()); } - } } - t = layout.getFooter(); - - if (t != null) { - sbuf.append(t); - } - part.setContent(sbuf.toString(), layout.getContentType() + ";charset=" + charset); Multipart mp = new MimeMultipart(); mp.addBodyPart(part); @@ -392,63 +415,79 @@ protected void sendBuffer(LoggingEvent triggeringEvent) { msg.setSentDate(new Date()); Transport.send(msg); - } catch (Exception e) { - getLogger().error("Error occured while sending e-mail notification.", e); + } catch(MessagingException e) { + LogLog.error("Error occured while sending e-mail notification.", e); + } catch(RuntimeException e) { + LogLog.error("Error occured while sending e-mail notification.", e); } } - String computeSubject(LoggingEvent triggeringEvent) { - if (subjectLayout != null) { - return subjectLayout.format(triggeringEvent); - } - return null; - } + /** Returns value of the EvaluatorClass option. */ - public String getEvaluatorClass() { - return (evaluator == null) ? null : evaluator.getClass().getName(); + public + String getEvaluatorClass() { + return evaluator == null ? null : evaluator.getClass().getName(); } /** Returns value of the From option. */ - public String getFrom() { + public + String getFrom() { return from; } - + + /** + Get the reply addresses. + @return reply addresses as comma separated string, may be null. + @since 1.2.16 + */ + public + String getReplyTo() { + return replyTo; + } + /** Returns value of the Subject option. */ - public String getSubject() { - return subjectStr; + public + String getSubject() { + return subject; } /** The From option takes a string value which should be a e-mail address of the sender. */ - public void setFrom(String from) { + public + void setFrom(String from) { this.from = from; } /** - * The Subject option takes a string value which will be the subject - * of the e-mail message. This value can be string literal or a conversion - * pattern in the same format as expected by - * {@link org.apache.log4j.PatternLayout}. - * - *

    The conversion pattern is applied on the triggering event to dynamically - * compute the subject of the outging email message. For example, setting - * the Subject option to "%properties{host} - %m" - * will set the subject of outgoing message to the "host" property of the - * triggering event followed by the message of the triggering event. + Set the e-mail addresses to which replies should be directed. + @param addresses reply addresses as comma separated string, may be null. + @since 1.2.16 + */ + public + void setReplyTo(final String addresses) { + this.replyTo = addresses; + } + + + /** + The Subject option takes a string value which should be a + the subject of the e-mail message. */ - public void setSubject(String subject) { - this.subjectStr = subject; + public + void setSubject(String subject) { + this.subject = subject; } + /** The BufferSize option takes a positive integer representing the maximum number of logging events to collect in a @@ -456,7 +495,8 @@ public void setSubject(String subject) { oldest events are deleted as new events are added to the buffer. By default the size of the cyclic buffer is 512 events. */ - public void setBufferSize(int bufferSize) { + public + void setBufferSize(int bufferSize) { this.bufferSize = bufferSize; cb.resize(bufferSize); } @@ -465,14 +505,16 @@ public void setBufferSize(int bufferSize) { The SMTPHost option takes a string value which should be a the host name of the SMTP server that will send the e-mail message. */ - public void setSMTPHost(String smtpHost) { + public + void setSMTPHost(String smtpHost) { this.smtpHost = smtpHost; } /** Returns value of the SMTPHost option. */ - public String getSMTPHost() { + public + String getSMTPHost() { return smtpHost; } @@ -480,38 +522,34 @@ public String getSMTPHost() { The To option takes a string value which should be a comma separated list of e-mail address of the recipients. */ - public void setTo(String to) { + public + void setTo(String to) { this.to = to; } + + /** Returns value of the BufferSize option. */ - public int getBufferSize() { + public + int getBufferSize() { return bufferSize; } /** - * The EvaluatorClass option takes a string value representing the - * name of the class implementing the {@link TriggeringEventEvaluator} - * interface. A corresponding object will be instantiated and assigned as - * the triggering event evaluator for the SMTPAppender. - * - * @deprecated replaced by {@link #setEvaluator}. + The EvaluatorClass option takes a string value + representing the name of the class implementing the {@link + TriggeringEventEvaluator} interface. A corresponding object will + be instantiated and assigned as the triggering event evaluator + for the SMTPAppender. */ - public void setEvaluatorClass(String value) { - getLogger().warn("The SMPTAppender.setEvaluatorClass is deprecated."); - getLogger().warn("It has been replaced with the more powerful SMPTAppender.setEvaluator method."); - evaluator = - (TriggeringEventEvaluator) OptionConverter.instantiateByClassName( - value, TriggeringEventEvaluator.class, evaluator); - } - - /** - * Set {@link TriggeringEventEvaluator} for this instance of SMTPAppender. - */ - public void setEvaluator(TriggeringEventEvaluator evaluator) { - this.evaluator = evaluator; + public + void setEvaluatorClass(String value) { + evaluator = (TriggeringEventEvaluator) + OptionConverter.instantiateByClassName(value, + TriggeringEventEvaluator.class, + evaluator); } @@ -526,37 +564,23 @@ public void setEvaluator(TriggeringEventEvaluator evaluator) {

    Location information extraction is comparatively very slow and should be avoided unless performance is not a concern. */ - public void setLocationInfo(boolean locationInfo) { + public + void setLocationInfo(boolean locationInfo) { this.locationInfo = locationInfo; } /** Returns value of the LocationInfo option. */ - public boolean getLocationInfo() { + public + boolean getLocationInfo() { return locationInfo; } - - /** - * Set charset for messages: ensure the charset - * you are using is available on your platform. - */ - public void setCharset(String charset) { - this.charset = charset; - } - - /** - * Returns the charset for messages. The default - * is "ISO-8859-1." This method should not return - * null. - */ - public String getCharset() { - return charset; - } - + /** Set the cc recipient addresses. @param addresses recipient addresses as comma separated string, may be null. + @since 1.2.14 */ public void setCc(final String addresses) { this.cc = addresses; @@ -565,6 +589,7 @@ public void setCc(final String addresses) { /** Get the cc recipient addresses. @return recipient addresses as comma separated string, may be null. + @since 1.2.14 */ public String getCc() { return cc; @@ -573,6 +598,7 @@ public String getCc() { /** Set the bcc recipient addresses. @param addresses recipient addresses as comma separated string, may be null. + @since 1.2.14 */ public void setBcc(final String addresses) { this.bcc = addresses; @@ -581,6 +607,7 @@ public void setBcc(final String addresses) { /** Get the bcc recipient addresses. @return recipient addresses as comma separated string, may be null. + @since 1.2.14 */ public String getBcc() { return bcc; @@ -590,6 +617,7 @@ public String getBcc() { * The SmtpPassword option takes a string value which should be the password required to authenticate against * the mail server. * @param password password, may be null. + * @since 1.2.14 */ public void setSMTPPassword(final String password) { this.smtpPassword = password; @@ -599,6 +627,7 @@ public void setSMTPPassword(final String password) { * The SmtpUsername option takes a string value which should be the username required to authenticate against * the mail server. * @param username user name, may be null. + * @since 1.2.14 */ public void setSMTPUsername(final String username) { this.smtpUsername = username; @@ -609,6 +638,7 @@ public void setSMTPUsername(final String username) { * This can be useful when debuging the appender but should not be used during production because username and * password information is included in the output. * @param debug debug flag. + * @since 1.2.14 */ public void setSMTPDebug(final boolean debug) { this.smtpDebug = debug; @@ -617,6 +647,7 @@ public void setSMTPDebug(final boolean debug) { /** * Get SMTP password. * @return SMTP password, may be null. + * @since 1.2.14 */ public String getSMTPPassword() { return smtpPassword; @@ -625,6 +656,7 @@ public String getSMTPPassword() { /** * Get SMTP user name. * @return SMTP user name, may be null. + * @since 1.2.14 */ public String getSMTPUsername() { return smtpUsername; @@ -633,74 +665,124 @@ public String getSMTPUsername() { /** * Get SMTP debug. * @return SMTP debug flag. + * @since 1.2.14 */ public boolean getSMTPDebug() { return smtpDebug; } - /** - * Returns the session JNDI entry name. - * This is useful for application servers. - */ - public String getSessionJNDI() { - return sessionJNDI; + /** + * Sets triggering evaluator. + * @param trigger triggering event evaluator. + * @since 1.2.15 + */ + public final void setEvaluator(final TriggeringEventEvaluator trigger) { + if (trigger == null) { + throw new NullPointerException("trigger"); + } + this.evaluator = trigger; } - /** - * Sets the session JNDI entry name. - */ - public void setSessionJNDI(String sessionJndiLocation) { - this.sessionJNDI = sessionJndiLocation; + /** + * Get triggering evaluator. + * @return triggering event evaluator. + * @since 1.2.15 + */ + public final TriggeringEventEvaluator getEvaluator() { + return evaluator; + } + + /** {@inheritDoc} + * @since 1.2.15 + */ + public boolean parseUnrecognizedElement(final Element element, + final Properties props) throws Exception { + if ("triggeringPolicy".equals(element.getNodeName())) { + Object triggerPolicy = + org.apache.log4j.xml.DOMConfigurator.parseElement( + element, props, TriggeringEventEvaluator.class); + if (triggerPolicy instanceof TriggeringEventEvaluator) { + setEvaluator((TriggeringEventEvaluator) triggerPolicy); + } + return true; + } + + return false; } - /** - * Returns the SMTP port to use. - */ - public int getSMTPPort() { - return smtpPort; + /** + * Get transport protocol. + * Typically null or "smtps". + * + * @return transport protocol, may be null. + * @since 1.2.16 + */ + public final String getSMTPProtocol() { + return smtpProtocol; } - /** - * Sets the SMTP port to use. - */ - public void setSMTPPort(int smtpPort) { - this.smtpPort = smtpPort; + /** + * Set transport protocol. + * Typically null or "smtps". + * + * @param val transport protocol, may be null. + * @since 1.2.16 + */ + public final void setSMTPProtocol(final String val) { + smtpProtocol = val; } - -} + /** + * Get port. + * + * @return port, negative values indicate use of default ports for protocol. + * @since 1.2.16 + */ + public final int getSMTPPort() { + return smtpPort; + } -class DefaultEvaluator extends ComponentBase implements TriggeringEventEvaluator { + /** + * Set port. + * + * @param val port, negative values indicate use of default ports for protocol. + * @since 1.2.16 + */ + public final void setSMTPPort(final int val) { + smtpPort = val; + } - private Rule expressionRule; - private String expression; - - public DefaultEvaluator() {} - - public void setExpression(String expression) { - this.expression = expression; + /** + * Get sendOnClose. + * + * @return if true all buffered logging events will be sent when the appender is closed. + * @since 1.2.16 + */ + public final boolean getSendOnClose() { + return sendOnClose; } - - public void activateOptions() { - if(expression != null) { - try { - expressionRule = ExpressionRule.getRule(expression); - } catch (IllegalArgumentException iae) { - getLogger().error("Unable to use provided expression - falling back to default behavior (trigger on ERROR or greater severity)", iae); - } - } + + /** + * Set sendOnClose. + * + * @param val if true all buffered logging events will be sent when appender is closed. + * @since 1.2.16 + */ + public final void setSendOnClose(final boolean val) { + sendOnClose = val; } - + +} + +class DefaultEvaluator implements TriggeringEventEvaluator { /** Is this event the e-mail triggering event?

    This method returns true, if the event level has ERROR level or higher. Otherwise it returns false. */ - public boolean isTriggeringEvent(LoggingEvent event) { - if (expressionRule == null) { - return event.getLevel().isGreaterOrEqual(Level.ERROR); - } - return expressionRule.evaluate(event); + public + boolean isTriggeringEvent(LoggingEvent event) { + return event.getLevel().isGreaterOrEqual(Level.ERROR); } } diff --git a/src/main/java/org/apache/log4j/net/SimpleSocketServer.java b/src/main/java/org/apache/log4j/net/SimpleSocketServer.java index e185803900..2afdbff899 100644 --- a/src/main/java/org/apache/log4j/net/SimpleSocketServer.java +++ b/src/main/java/org/apache/log4j/net/SimpleSocketServer.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,14 +17,14 @@ package org.apache.log4j.net; -import org.apache.log4j.Logger; -import org.apache.log4j.LogManager; -import org.apache.log4j.PropertyConfigurator; -import org.apache.log4j.joran.JoranConfigurator; - import java.net.ServerSocket; import java.net.Socket; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; +import org.apache.log4j.xml.DOMConfigurator; + /** * A simple {@link SocketNode} based server. @@ -32,63 +32,64 @@

        Usage: java org.apache.log4j.net.SimpleSocketServer port configFile
     
    -   where port is a part number where the server listens and
    +   where port is a port number where the server listens and
        configFile is a configuration file fed to the {@link
    -   PropertyConfigurator} or to {@link JoranConfigurator} if an XML file.
    +   PropertyConfigurator} or to {@link DOMConfigurator} if an XML file.
        
    * * @author Ceki Gülcü * - * @since 0.8.4 + * @since 0.8.4 * */ -public class SimpleSocketServer { - final static Logger logger = Logger.getLogger(SimpleSocketServer.class); +public class SimpleSocketServer { + + static Logger cat = Logger.getLogger(SimpleSocketServer.class); + static int port; - public static void main(String[] argv) { - if (argv.length == 2) { + public + static + void main(String argv[]) { + if(argv.length == 2) { init(argv[0], argv[1]); } else { usage("Wrong number of arguments."); } - + try { - logger.info("Listening on port " + port); - + cat.info("Listening on port " + port); ServerSocket serverSocket = new ServerSocket(port); - - while (true) { - logger.info("Waiting to accept a new client."); - - Socket socket = serverSocket.accept(); - logger.info("Connected to client at " + socket.getInetAddress()); - logger.info("Starting new socket node."); - new Thread(new SocketNode(socket, LogManager.getLoggerRepository())) - .start(); + while(true) { + cat.info("Waiting to accept a new client."); + Socket socket = serverSocket.accept(); + cat.info("Connected to client at " + socket.getInetAddress()); + cat.info("Starting new socket node."); + new Thread(new SocketNode(socket, + LogManager.getLoggerRepository()),"SimpleSocketServer-" + port).start(); } - } catch (Exception e) { + } catch(Exception e) { e.printStackTrace(); } } - static void usage(String msg) { + + static void usage(String msg) { System.err.println(msg); System.err.println( - "Usage: java " + SimpleSocketServer.class.getName() + " port configFile"); + "Usage: java " +SimpleSocketServer.class.getName() + " port configFile"); System.exit(1); } static void init(String portStr, String configFile) { try { port = Integer.parseInt(portStr); - } catch (java.lang.NumberFormatException e) { + } catch(java.lang.NumberFormatException e) { e.printStackTrace(); - usage("Could not interpret port number [" + portStr + "]."); + usage("Could not interpret port number ["+ portStr +"]."); } - - if (configFile.endsWith(".xml")) { - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure(configFile, LogManager.getLoggerRepository()); + + if(configFile.endsWith(".xml")) { + DOMConfigurator.configure(configFile); } else { PropertyConfigurator.configure(configFile); } diff --git a/src/main/java/org/apache/log4j/net/SocketAppender.java b/src/main/java/org/apache/log4j/net/SocketAppender.java index ef4d0e7ee9..88f0049835 100644 --- a/src/main/java/org/apache/log4j/net/SocketAppender.java +++ b/src/main/java/org/apache/log4j/net/SocketAppender.java @@ -15,273 +15,296 @@ * limitations under the License. */ - // Contributors: Dan MacDonald -package org.apache.log4j.net; -import org.apache.log4j.AppenderSkeleton; -import org.apache.log4j.helpers.Constants; -import org.apache.log4j.spi.LoggingEvent; +package org.apache.log4j.net; import java.io.IOException; import java.io.ObjectOutputStream; - +import java.io.InterruptedIOException; import java.net.InetAddress; import java.net.Socket; -import java.net.UnknownHostException; +import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.spi.ErrorCode; +import org.apache.log4j.spi.LoggingEvent; /** - * Sends {@link LoggingEvent} objects to a remote a log server, usually a - * {@link SocketNode}. - *

    - * The SocketAppender has the following properties: - * - *

      - *
    • If sent to a {@link SocketNode}, remote logging is non-intrusive as - * far as the log event is concerned. In other words, the event will be logged - * with the same time stamp, {@link org.apache.log4j.NDC}, location info as if - * it were logged locally by the client. - *
    • - * - *
    • SocketAppenders do not use a layout. They ship a serialized - * {@link LoggingEvent} object to the server side.
    • - * - *
    • Remote logging uses the TCP protocol. Consequently, if the server is - * reachable, then log events will eventually arrive at the server. - * - *

    • If the remote server is down, the logging requests are simply dropped. - * However, if and when the server comes back up then event transmission is - * resumed transparently. This transparent reconneciton is performed by a - * connector thread which periodically attempts to connect to - * the server. - * - *

    • Logging events are automatically buffered by the native TCP - * implementation. This means that if the link to server is slow but still - * faster than the rate of (log) event production by the client, the client will - * not be affected by the slow network connection. However, if the network - * connection is slower then the rate of event production, then the client can - * only progress at the network rate. In particular, if the network link to the - * the server is down, the client will be blocked. - * - *

      On the other hand, if the network link is up, but the server is down, the - * client will not be blocked when making log requests but the log events will - * be lost due to server unavailability. - * - *

    • Even if a SocketAppender is no longer attached to any - * category, it will not be garbage collected in the presence of a connector - * thread. A connector thread exists only if the connection to the server is - * down. To avoid this garbage collection problem, you should {@link #close} - * the the SocketAppender explicitly. See also next item. - * - *

      Long lived applications which create/destroy many - * SocketAppender instances should be aware of this garbage - * collection problem. Most other applications can safely ignore it. - * - *

    • If the JVM hosting the SocketAppender exits before the - * SocketAppender is closed either explicitly or subsequent to - * garbage collection, then there might be untransmitted data in the pipe - * which might be lost. This is a common problem on Windows based systems. - * - *

      To avoid lost data, it is usually sufficient to {@link #close} the - * SocketAppender either explicitly or by calling the - * {@link org.apache.log4j.LogManager#shutdown} method before exiting the - * application. - * - *

    - * - * @author Ceki Gülcü - * @since 0.8.4 - * */ + Sends {@link LoggingEvent} objects to a remote a log server, + usually a {@link SocketNode}. + +

    The SocketAppender has the following properties: + +

      + +

    • If sent to a {@link SocketNode}, remote logging is + non-intrusive as far as the log event is concerned. In other + words, the event will be logged with the same time stamp, {@link + org.apache.log4j.NDC}, location info as if it were logged locally by + the client. + +

    • SocketAppenders do not use a layout. They ship a + serialized {@link LoggingEvent} object to the server side. + +

    • Remote logging uses the TCP protocol. Consequently, if + the server is reachable, then log events will eventually arrive + at the server. + +

    • If the remote server is down, the logging requests are + simply dropped. However, if and when the server comes back up, + then event transmission is resumed transparently. This + transparent reconneciton is performed by a connector + thread which periodically attempts to connect to the server. + +

    • Logging events are automatically buffered by the + native TCP implementation. This means that if the link to server + is slow but still faster than the rate of (log) event production + by the client, the client will not be affected by the slow + network connection. However, if the network connection is slower + then the rate of event production, then the client can only + progress at the network rate. In particular, if the network link + to the the server is down, the client will be blocked. + +

      On the other hand, if the network link is up, but the server + is down, the client will not be blocked when making log requests + but the log events will be lost due to server unavailability. + +

    • Even if a SocketAppender is no longer + attached to any category, it will not be garbage collected in + the presence of a connector thread. A connector thread exists + only if the connection to the server is down. To avoid this + garbage collection problem, you should {@link #close} the the + SocketAppender explicitly. See also next item. + +

      Long lived applications which create/destroy many + SocketAppender instances should be aware of this + garbage collection problem. Most other applications can safely + ignore it. + +

    • If the JVM hosting the SocketAppender exits + before the SocketAppender is closed either + explicitly or subsequent to garbage collection, then there might + be untransmitted data in the pipe which might be lost. This is a + common problem on Windows based systems. + +

      To avoid lost data, it is usually sufficient to {@link + #close} the SocketAppender either explicitly or by + calling the {@link org.apache.log4j.LogManager#shutdown} method + before exiting the application. + + +

    + + @author Ceki Gülcü + @since 0.8.4 */ + public class SocketAppender extends AppenderSkeleton { + /** - * The default port number of remote logging server (4560). - */ - public static final int DEFAULT_PORT = 4560; + The default port number of remote logging server (4560). + @since 1.2.15 + */ + static public final int DEFAULT_PORT = 4560; /** - * The default reconnection delay (30000 milliseconds or 30 seconds). - */ - static final int DEFAULT_RECONNECTION_DELAY = 30000; + The default reconnection delay (30000 milliseconds or 30 seconds). + */ + static final int DEFAULT_RECONNECTION_DELAY = 30000; - // reset the ObjectOutputStream every 70 calls - //private static final int RESET_FREQUENCY = 70; - private static final int RESET_FREQUENCY = 1; + /** + We remember host name as String in addition to the resolved + InetAddress so that it can be returned via getOption(). + */ + String remoteHost; /** - * We remember host name as String in addition to the resolved - * InetAddress so that it can be returned via getOption(). + * The MulticastDNS zone advertised by a SocketAppender */ - String remoteHost; + public static final String ZONE = "_log4j_obj_tcpconnect_appender.local."; + InetAddress address; int port = DEFAULT_PORT; ObjectOutputStream oos; int reconnectionDelay = DEFAULT_RECONNECTION_DELAY; boolean locationInfo = false; + private String application; + private Connector connector; + int counter = 0; - String hostname; - String application; + + // reset the ObjectOutputStream every 70 calls + //private static final int RESET_FREQUENCY = 70; + private static final int RESET_FREQUENCY = 1; + private boolean advertiseViaMulticastDNS; + private ZeroConfSupport zeroConf; public SocketAppender() { - super(false); } /** - Connects to remote server at address and port. + Connects to remote server at address and port. */ public SocketAppender(InetAddress address, int port) { - super(false); this.address = address; this.remoteHost = address.getHostName(); this.port = port; - activateOptions(); + connect(address, port); } /** - Connects to remote server at host and port. + Connects to remote server at host and port. */ public SocketAppender(String host, int port) { - super(false); this.port = port; this.address = getAddressByName(host); this.remoteHost = host; - activateOptions(); + connect(address, port); } /** - Connect to the specified RemoteHost and Port. + Connect to the specified RemoteHost and Port. */ public void activateOptions() { - try { - hostname = InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException uhe) { - try { - hostname = InetAddress.getLocalHost().getHostAddress(); - } catch (UnknownHostException uhe2) { - hostname = "unknown"; - } - } - if(remoteHost != null) { - address = getAddressByName(remoteHost); - connect(address, port); - } else { - String err = "The RemoteHost property is required for SocketAppender named "+ name; - getLogger().error(err); - throw new IllegalStateException(err); + if (advertiseViaMulticastDNS) { + zeroConf = new ZeroConfSupport(ZONE, port, getName()); + zeroConf.advertise(); } - // all is dandy on the eastern front. - super.activateOptions(); + connect(address, port); } /** - * Close this appender. + * Close this appender. * *

    This will mark the appender as closed and call then {@link * #cleanUp} method. * */ - public synchronized void close() { - if (closed) { - return; + synchronized public void close() { + if(closed) { + return; } this.closed = true; + if (advertiseViaMulticastDNS) { + zeroConf.unadvertise(); + } + cleanUp(); } /** * Drop the connection to the remote host and release the underlying - * connector thread if it has been created + * connector thread if it has been created * */ public void cleanUp() { - if (oos != null) { + if(oos != null) { try { - oos.close(); - } catch (IOException e) { - getLogger().error("Could not close oos.", e); + oos.close(); + } catch(IOException e) { + if (e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.error("Could not close oos.", e); } - oos = null; } - - if (connector != null) { + if(connector != null) { //LogLog.debug("Interrupting the connector."); connector.interrupted = true; - connector = null; // allow gc + connector = null; // allow gc } } void connect(InetAddress address, int port) { - if (this.address == null) { - return; + if(this.address == null) { + return; } - try { // First, close the previous connection if any. cleanUp(); - oos = - new ObjectOutputStream(new Socket(address, port).getOutputStream()); - } catch (IOException e) { - String msg = - "Could not connect to remote log4j server at [" - + address.getHostName() + "]."; - - if (reconnectionDelay > 0) { - msg += " We will try again later."; - fireConnector(); // fire the connector thread + oos = new ObjectOutputStream(new Socket(address, port).getOutputStream()); + } catch(IOException e) { + if (e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); } - - /** - * Rather than log an ugly stack trace, output the msg - */ - getLogger().error(msg + "(" + e.getMessage() + ")"); + String msg = "Could not connect to remote log4j server at [" + +address.getHostName()+"]."; + if(reconnectionDelay > 0) { + msg += " We will try again later."; + fireConnector(); // fire the connector thread + } else { + msg += " We are not retrying."; + errorHandler.error(msg, e, ErrorCode.GENERIC_FAILURE); + } + LogLog.error(msg); } } + public void append(LoggingEvent event) { - if (event == null) { + if(event == null) { + return; + } + + if(address==null) { + errorHandler.error("No remote host is set for SocketAppender named \""+ + this.name+"\"."); return; } - if (oos != null) { + if(oos != null) { try { - if (locationInfo) { - event.getLocationInformation(); - } - - if (hostname != null) { - event.setProperty(Constants.HOSTNAME_KEY, hostname); - } - - if (application != null) { - event.setProperty(Constants.APPLICATION_KEY, application); - } - - oos.writeObject(event); - oos.flush(); - - if (++counter >= RESET_FREQUENCY) { - counter = 0; - - // Failing to reset the object output stream every now and - // then creates a serious memory leak. - //System.err.println("Doing oos.reset()"); - oos.reset(); - } - } catch (IOException e) { - oos = null; - getLogger().warn("Detected problem with connection: " + e); - - if (reconnectionDelay > 0) { - fireConnector(); - } + + if(locationInfo) { + event.getLocationInformation(); + } + if (application != null) { + event.setProperty("application", application); + } + event.getNDC(); + event.getThreadName(); + event.getMDCCopy(); + event.getRenderedMessage(); + event.getThrowableStrRep(); + + oos.writeObject(event); + //LogLog.debug("=========Flushing."); + oos.flush(); + if(++counter >= RESET_FREQUENCY) { + counter = 0; + // Failing to reset the object output stream every now and + // then creates a serious memory leak. + //System.err.println("Doing oos.reset()"); + oos.reset(); + } + } catch(IOException e) { + if (e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + oos = null; + LogLog.warn("Detected problem with connection: "+e); + if(reconnectionDelay > 0) { + fireConnector(); + } else { + errorHandler.error("Detected problem with connection, not reconnecting.", e, + ErrorCode.GENERIC_FAILURE); + } } } } + public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) { + this.advertiseViaMulticastDNS = advertiseViaMulticastDNS; + } + + public boolean isAdvertiseViaMulticastDNS() { + return advertiseViaMulticastDNS; + } + void fireConnector() { - if (connector == null) { - getLogger().debug("Starting a new connector thread."); + if(connector == null) { + LogLog.debug("Starting a new connector thread."); connector = new Connector(); connector.setDaemon(true); connector.setPriority(Thread.MIN_PRIORITY); @@ -289,57 +312,70 @@ void fireConnector() { } } + static InetAddress getAddressByName(String host) { try { return InetAddress.getByName(host); - } catch (Exception e) { - getLogger().error("Could not find address of [" + host + "].", e); + } catch(Exception e) { + if (e instanceof InterruptedIOException || e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } + LogLog.error("Could not find address of ["+host+"].", e); return null; } } + /** + * The SocketAppender does not use a layout. Hence, this method + * returns false. + * */ + public boolean requiresLayout() { + return false; + } + /** * The RemoteHost option takes a string value which should be - * the host name of the server where a {@link SocketNode} or a - * {@link SocketReceiver} is running. + * the host name of the server where a {@link SocketNode} is + * running. * */ public void setRemoteHost(String host) { + address = getAddressByName(host); remoteHost = host; } /** - * Returns value of the RemoteHost option. + Returns value of the RemoteHost option. */ public String getRemoteHost() { return remoteHost; } /** - * The Port option takes a positive integer representing the port - * where the server is waiting for connections. + The Port option takes a positive integer representing + the port where the server is waiting for connections. */ public void setPort(int port) { this.port = port; } /** - * Returns value of the Port option. + Returns value of the Port option. */ public int getPort() { return port; } /** - * The LocationInfo option takes a boolean value. If true, the - * information sent to the remote host will include location information. - * By default no location information is sent to the server. + The LocationInfo option takes a boolean value. If true, + the information sent to the remote host will include location + information. By default no location information is sent to the server. */ public void setLocationInfo(boolean locationInfo) { this.locationInfo = locationInfo; } /** - * Returns value of the LocationInfo option. + Returns value of the LocationInfo option. */ public boolean getLocationInfo() { return locationInfo; @@ -349,6 +385,7 @@ public boolean getLocationInfo() { * The App option takes a string value which should be the name of the * application getting logged. * If property was already set (via system property), don't set here. + * @since 1.2.15 */ public void setApplication(String lapp) { this.application = lapp; @@ -356,73 +393,76 @@ public void setApplication(String lapp) { /** * Returns value of the Application option. + * @since 1.2.15 */ public String getApplication() { return application; } /** - * The ReconnectionDelay option takes a positive integer representing - * the number of milliseconds to wait between each failed connection attempt - * to the server. The default value of this option is 30000 which corresponds - * to 30 seconds. - *

    - * Setting this option to zero turns off reconnection capability. + The ReconnectionDelay option takes a positive integer + representing the number of milliseconds to wait between each + failed connection attempt to the server. The default value of + this option is 30000 which corresponds to 30 seconds. + +

    Setting this option to zero turns off reconnection + capability. */ public void setReconnectionDelay(int delay) { this.reconnectionDelay = delay; } /** - * Returns value of the ReconnectionDelay option. + Returns value of the ReconnectionDelay option. */ public int getReconnectionDelay() { return reconnectionDelay; } /** - * The Connector will reconnect when the server becomes available again. - * It does this by attempting to open a new connection every - * reconnectionDelay milliseconds. - *

    - * It stops trying whenever a connection is established. It will restart to - * try reconnect to the server when previpously open connection is droppped. - * - * @author Ceki Gülcü - * @since 0.8.4 + The Connector will reconnect when the server becomes available + again. It does this by attempting to open a new connection every + reconnectionDelay milliseconds. + +

    It stops trying whenever a connection is established. It will + restart to try reconnect to the server when previously open + connection is droppped. + + @author Ceki Gülcü + @since 0.8.4 */ class Connector extends Thread { + boolean interrupted = false; - public void run() { + public + void run() { Socket socket; - - while (!interrupted) { - try { - sleep(reconnectionDelay); - getLogger().debug("Attempting connection to {}", address.getHostName()); - socket = new Socket(address, port); - - synchronized (this) { - oos = new ObjectOutputStream(socket.getOutputStream()); - connector = null; - getLogger().debug("Connection established. Exiting connector thread."); - - break; - } - } catch (InterruptedException e) { - getLogger().debug("Connector interrupted. Leaving loop."); - - return; - } catch (java.net.ConnectException e) { - getLogger().debug( - "Remote host " + address.getHostName() + " refused connection."); - } catch (IOException e) { - getLogger().debug( - "Could not connect to {}. Exception is {}", address.getHostName(), e); + while(!interrupted) { + try { + sleep(reconnectionDelay); + LogLog.debug("Attempting connection to "+address.getHostName()); + socket = new Socket(address, port); + synchronized(this) { + oos = new ObjectOutputStream(socket.getOutputStream()); + connector = null; + LogLog.debug("Connection established. Exiting connector thread."); + break; + } + } catch(InterruptedException e) { + LogLog.debug("Connector interrupted. Leaving loop."); + return; + } catch(java.net.ConnectException e) { + LogLog.debug("Remote host "+address.getHostName() + +" refused connection."); + } catch(IOException e) { + if (e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); } + LogLog.debug("Could not connect to " + address.getHostName()+ + ". Exception is " + e); + } } - //LogLog.debug("Exiting Connector.run() method."); } @@ -434,12 +474,4 @@ void finalize() { */ } - /** - * Gets whether appender requires a layout. - * @return false - */ - public boolean requiresLayout() { - return false; - } - } diff --git a/src/main/java/org/apache/log4j/net/SocketHubAppender.java b/src/main/java/org/apache/log4j/net/SocketHubAppender.java index 72084c0df8..74d7186ea0 100644 --- a/src/main/java/org/apache/log4j/net/SocketHubAppender.java +++ b/src/main/java/org/apache/log4j/net/SocketHubAppender.java @@ -28,13 +28,13 @@ import org.apache.log4j.AppenderSkeleton; import org.apache.log4j.helpers.CyclicBuffer; +import org.apache.log4j.helpers.LogLog; import org.apache.log4j.spi.LoggingEvent; - /** Sends {@link LoggingEvent} objects to a set of remote log servers, usually a {@link SocketNode SocketNodes}. - +

    Acts just like {@link SocketAppender} except that instead of connecting to a given remote log server, SocketHubAppender accepts connections from the remote @@ -44,7 +44,7 @@ not require any update to the configuration file to send data to another remote log server. The remote log server simply connects to the host and port the SocketHubAppender is running on. - +

    The SocketHubAppender does not store events such that the remote side will events that arrived after the establishment of its connection. Once connected, events arrive in @@ -54,24 +54,24 @@ SocketAppender}.

    The SocketHubAppender has the following characteristics: - +

      - +

    • If sent to a {@link SocketNode}, logging is non-intrusive as far as the log event is concerned. In other words, the event will be logged with the same time stamp, {@link org.apache.log4j.NDC}, location info as if it were logged locally. - +

    • SocketHubAppender does not use a layout. It ships a serialized {@link LoggingEvent} object to the remote side. - +

    • SocketHubAppender relies on the TCP protocol. Consequently, if the remote side is reachable, then log events will eventually arrive at remote client. - +

    • If no remote clients are attached, the logging requests are simply dropped. - +

    • Logging events are automatically buffered by the native TCP implementation. This means that if the link to remote client is slow but still faster than the rate of (log) event @@ -80,218 +80,293 @@ client is slow but still faster than the rate of (log) event rate of event production, then the local application can only progress at the network rate. In particular, if the network link to the the remote client is down, the application will be blocked. - +

      On the other hand, if the network link is up, but the remote client is down, the client will not be blocked when making log requests but the log events will be lost due to client - unavailability. + unavailability.

      The single remote client case extends to multiple clients connections. The rate of logging will be determined by the slowest link. - -

      The BufferSize param provides a cyclic buffer of recently appended events. - As new clients attach to the SocketHubAppender, the clients also receive the buffered - events. - +

    • If the JVM hosting the SocketHubAppender exits before the SocketHubAppender is closed either explicitly or subsequent to garbage collection, then there might be untransmitted data in the pipe which might be lost. This is a common problem on Windows based systems. - +

      To avoid lost data, it is usually sufficient to {@link #close} the SocketHubAppender either explicitly or by calling the {@link org.apache.log4j.LogManager#shutdown} method before exiting the application. - +

    - + @author Mark Womack */ + public class SocketHubAppender extends AppenderSkeleton { + /** The default port number of the ServerSocket will be created on. */ - public static final int DEFAULT_PORT = 4560; + static final int DEFAULT_PORT = 4560; + private int port = DEFAULT_PORT; private Vector oosList = new Vector(); private ServerMonitor serverMonitor = null; private boolean locationInfo = false; private CyclicBuffer buffer = null; + private String application; + private boolean advertiseViaMulticastDNS; + private ZeroConfSupport zeroConf; - public SocketHubAppender() { - super(false); - } + /** + * The MulticastDNS zone advertised by a SocketHubAppender + */ + public static final String ZONE = "_log4j_obj_tcpaccept_appender.local."; + private ServerSocket serverSocket; + + + public SocketHubAppender() { } /** Connects to remote server at address and port. */ - public SocketHubAppender(int _port) { - super(false); + public + SocketHubAppender(int _port) { port = _port; - activateOptions(); + startServer(); } /** Set up the socket server on the specified port. */ - public void activateOptions() { + public + void activateOptions() { + if (advertiseViaMulticastDNS) { + zeroConf = new ZeroConfSupport(ZONE, port, getName()); + zeroConf.advertise(); + } startServer(); - super.activateOptions(); } /** - Close this appender. + Close this appender.

    This will mark the appender as closed and call then {@link #cleanUp} method. */ - public synchronized void close() { - if (closed) { - return; + synchronized + public + void close() { + if(closed) { + return; } - getLogger().debug("closing SocketHubAppender {}", getName()); + LogLog.debug("closing SocketHubAppender " + getName()); this.closed = true; + if (advertiseViaMulticastDNS) { + zeroConf.unadvertise(); + } cleanUp(); - getLogger().debug("SocketHubAppender {} closed", getName()); + + LogLog.debug("SocketHubAppender " + getName() + " closed"); } /** Release the underlying ServerMonitor thread, and drop the connections to all connected remote servers. */ - public void cleanUp() { + public + void cleanUp() { // stop the monitor thread - getLogger().debug("stopping ServerSocket"); - - if(serverMonitor != null) { - serverMonitor.stopMonitor(); - serverMonitor = null; - } + LogLog.debug("stopping ServerSocket"); + serverMonitor.stopMonitor(); + serverMonitor = null; // close all of the connections - getLogger().debug("closing client connections"); - + LogLog.debug("closing client connections"); while (oosList.size() != 0) { - ObjectOutputStream oos = (ObjectOutputStream) oosList.elementAt(0); - - if (oos != null) { + ObjectOutputStream oos = (ObjectOutputStream)oosList.elementAt(0); + if(oos != null) { try { - oos.close(); - } catch (IOException e) { - getLogger().error("could not close oos.", e); + oos.close(); + } catch(InterruptedIOException e) { + Thread.currentThread().interrupt(); + LogLog.error("could not close oos.", e); + } catch(IOException e) { + LogLog.error("could not close oos.", e); } - - oosList.removeElementAt(0); + + oosList.removeElementAt(0); } } } /** Append an event to all of current connections. */ - public void append(LoggingEvent event) { + public + void append(LoggingEvent event) { if (event != null) { - // set up location info if requested - if (locationInfo) { - event.getLocationInformation(); - } - if (buffer != null) { - buffer.add(event); - } + // set up location info if requested + if (locationInfo) { + event.getLocationInformation(); + } + if (application != null) { + event.setProperty("application", application); + } + event.getNDC(); + event.getThreadName(); + event.getMDCCopy(); + event.getRenderedMessage(); + event.getThrowableStrRep(); + + if (buffer != null) { + buffer.add(event); + } } - + // if no event or no open connections, exit now if ((event == null) || (oosList.size() == 0)) { return; } - // loop through the current set of open connections, appending the event to each - for (int streamCount = 0; streamCount < oosList.size(); streamCount++) { - ObjectOutputStream oos = null; + // loop through the current set of open connections, appending the event to each + for (int streamCount = 0; streamCount < oosList.size(); streamCount++) { + ObjectOutputStream oos = null; try { - oos = (ObjectOutputStream) oosList.elementAt(streamCount); - } catch (ArrayIndexOutOfBoundsException e) { + oos = (ObjectOutputStream)oosList.elementAt(streamCount); + } + catch (ArrayIndexOutOfBoundsException e) { // catch this, but just don't assign a value // this should not really occur as this method is // the only one that can remove oos's (besides cleanUp). } - + // list size changed unexpectedly? Just exit the append. if (oos == null) { break; - } - + } + try { - oos.writeObject(event); - oos.flush(); - - // Failing to reset the object output stream every now and - // then creates a serious memory leak. - // right now we always reset. TODO - set up frequency counter per oos? - oos.reset(); - } catch (IOException e) { - // there was an io exception so just drop the connection - oosList.removeElementAt(streamCount); - getLogger().debug("dropped connection"); - - // decrement to keep the counter in place (for loop always increments) - streamCount--; + oos.writeObject(event); + oos.flush(); + // Failing to reset the object output stream every now and + // then creates a serious memory leak. + // right now we always reset. TODO - set up frequency counter per oos? + oos.reset(); + } + catch(IOException e) { + if (e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + // there was an io exception so just drop the connection + oosList.removeElementAt(streamCount); + LogLog.debug("dropped connection"); + + // decrement to keep the counter in place (for loop always increments) + streamCount--; } } } - + /** The SocketHubAppender does not use a layout. Hence, this method returns false. */ - public boolean requiresLayout() { + public + boolean requiresLayout() { return false; } - + /** The Port option takes a positive integer representing the port where the server is waiting for connections. */ - public void setPort(int _port) { + public + void setPort(int _port) { port = _port; + } + + /** + * The App option takes a string value which should be the name of the application getting logged. If property was already set (via system + * property), don't set here. + */ + public + void setApplication(String lapp) { + this.application = lapp; } + /** + * Returns value of the Application option. + */ + public + String getApplication() { + return application; + } + /** Returns value of the Port option. */ - public int getPort() { + public + int getPort() { return port; } /** - The BufferSize option takes a positive integer representing - the number of events this appender will buffer and send to newly connected clients.*/ - public void setBufferSize(int _bufferSize) { + * The BufferSize option takes a positive integer representing the number of events this appender will buffer and send to newly connected + * clients. + */ + public + void setBufferSize(int _bufferSize) { buffer = new CyclicBuffer(_bufferSize); } /** - Returns value of the bufferSize option. */ - public int getBufferSize() { + * Returns value of the bufferSize option. + */ + public + int getBufferSize() { if (buffer == null) { - return 0; + return 0; } else { - return buffer.getMaxSize(); + return buffer.getMaxSize(); } } - + /** The LocationInfo option takes a boolean value. If true, the information sent to the remote host will include location information. By default no location information is sent to the server. */ - public void setLocationInfo(boolean _locationInfo) { + public + void setLocationInfo(boolean _locationInfo) { locationInfo = _locationInfo; } - + /** Returns value of the LocationInfo option. */ - public boolean getLocationInfo() { + public + boolean getLocationInfo() { return locationInfo; } + public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) { + this.advertiseViaMulticastDNS = advertiseViaMulticastDNS; + } + + public boolean isAdvertiseViaMulticastDNS() { + return advertiseViaMulticastDNS; + } + /** Start the ServerMonitor thread. */ - private void startServer() { + private + void startServer() { serverMonitor = new ServerMonitor(port, oosList); } + + /** + * Creates a server socket to accept connections. + * @param socketPort port on which the socket should listen, may be zero. + * @return new socket. + * @throws IOException IO error when opening the socket. + */ + protected ServerSocket createServerSocket(final int socketPort) throws IOException { + return new ServerSocket(socketPort); + } /** This class is used internally to monitor a ServerSocket @@ -305,117 +380,135 @@ private class ServerMonitor implements Runnable { /** Create a thread and start the monitor. */ - public ServerMonitor(int _port, Vector _oosList) { + public + ServerMonitor(int _port, Vector _oosList) { port = _port; oosList = _oosList; keepRunning = true; monitorThread = new Thread(this); monitorThread.setDaemon(true); + monitorThread.setName("SocketHubAppender-Monitor-" + port); monitorThread.start(); } - + /** Stops the monitor. This method will not return until the thread has finished executing. */ public synchronized void stopMonitor() { if (keepRunning) { - getLogger().debug("server monitor thread shutting down"); + LogLog.debug("server monitor thread shutting down"); keepRunning = false; + try { + if (serverSocket != null) { + serverSocket.close(); + serverSocket = null; + } + } catch (IOException ioe) {} try { monitorThread.join(); - } catch (InterruptedException e) { + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); // do nothing? } - + // release the thread monitorThread = null; - getLogger().debug("server monitor thread shut down"); + LogLog.debug("server monitor thread shut down"); } } - private void sendCachedEvents(ObjectOutputStream stream) throws IOException { - if (buffer != null) { - for (int i=0;i 0) { sendCachedEvents(oos); } - + // add it to the oosList. OK since Vector is synchronized. oosList.addElement(oos); } catch (IOException e) { - getLogger().error("exception creating output stream on socket.", e); + if (e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.error("exception creating output stream on socket.", e); } } } - } finally { - // close the socket - try { - serverSocket.close(); + } + finally { + // close the socket + try { + serverSocket.close(); + } catch(InterruptedIOException e) { + Thread.currentThread().interrupt(); } catch (IOException e) { - // do nothing with it? - } + // do nothing with it? + } } } } } + diff --git a/src/main/java/org/apache/log4j/net/SocketHubReceiver.java b/src/main/java/org/apache/log4j/net/SocketHubReceiver.java deleted file mode 100644 index 151bcfe029..0000000000 --- a/src/main/java/org/apache/log4j/net/SocketHubReceiver.java +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.net; - -import java.io.IOException; -import java.net.Socket; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.apache.log4j.plugins.Plugin; -import org.apache.log4j.plugins.Receiver; -import org.apache.log4j.spi.LoggerRepository; - -/** - SocketHubReceiver receives a remote logging event on a configured - socket and "posts" it to a LoggerRepository as if the event was - generated locally. This class is designed to receive events from - the SocketHubAppender class (or classes that send compatible events). - -

    Once the event has been "posted", it will be handled by the - appenders currently configured in the LoggerRespository. - - @author Mark Womack - @author Ceki Gülcü - @author Paul Smith (psmith@apache.org) - @since 1.3 -*/ -public class SocketHubReceiver -extends Receiver implements SocketNodeEventListener, PortBased { - - /** - * Default reconnection delay. - */ - static final int DEFAULT_RECONNECTION_DELAY = 30000; - - /** - * Host. - */ - protected String host; - - /** - * Port. - */ - protected int port; - /** - * Reconnection delay. - */ - protected int reconnectionDelay = DEFAULT_RECONNECTION_DELAY; - - /** - * Active. - */ - protected boolean active = false; - - /** - * Connector. - */ - protected Connector connector; - - /** - * Socket. - */ - protected Socket socket; - - /** - * Listener list. - */ - private List listenerList = Collections.synchronizedList(new ArrayList()); - - /** - * Create new instance. - */ - public SocketHubReceiver() { - super(); - } - - /** - * Create new instance. - * @param h host - * @param p port - */ - public SocketHubReceiver(final String h, - final int p) { - super(); - host = h; - port = p; - } - - /** - * Create new instance. - * @param h host - * @param p port - * @param repo logger repository - */ - public SocketHubReceiver(final String h, - final int p, - final LoggerRepository repo) { - super(); - host = h; - port = p; - repository = repo; - } - - /** - * Adds a SocketNodeEventListener to this receiver to be notified - * of SocketNode events. - * @param l listener - */ - public void addSocketNodeEventListener(final SocketNodeEventListener l) { - listenerList.add(l); - } - - /** - * Removes a specific SocketNodeEventListener from this instance - * so that it will no longer be notified of SocketNode events. - * @param l listener - */ - public void removeSocketNodeEventListener( - final SocketNodeEventListener l) { - listenerList.remove(l); - } - - /** - Get the remote host to connect to for logging events. - @return host - */ - public String getHost() { - return host; - } - - /** - * Configures the Host property, this will require activateOptions - * to be called for this to take effect. - * @param remoteHost address of remote host. - */ - public void setHost(final String remoteHost) { - this.host = remoteHost; - } - /** - Set the remote host to connect to for logging events. - Equivalent to setHost. - @param remoteHost address of remote host. - */ - public void setPort(final String remoteHost) { - host = remoteHost; - } - - /** - Get the remote port to connect to for logging events. - @return port - */ - public int getPort() { - return port; - } - - /** - Set the remote port to connect to for logging events. - @param p port - */ - public void setPort(final int p) { - this.port = p; - } - - /** - The ReconnectionDelay option takes a positive integer - representing the number of milliseconds to wait between each - failed connection attempt to the server. The default value of - this option is 30000 which corresponds to 30 seconds. - -

    Setting this option to zero turns off reconnection - capability. - @param delay milliseconds to wait or zero to not reconnect. - */ - public void setReconnectionDelay(final int delay) { - int oldValue = this.reconnectionDelay; - this.reconnectionDelay = delay; - firePropertyChange("reconnectionDelay", oldValue, this.reconnectionDelay); - } - - /** - Returns value of the ReconnectionDelay option. - @return value of reconnection delay option. - */ - public int getReconnectionDelay() { - return reconnectionDelay; - } - - /** - * Returns true if the receiver is the same class and they are - * configured for the same properties, and super class also considers - * them to be equivalent. This is used by PluginRegistry when determining - * if the a similarly configured receiver is being started. - * - * @param testPlugin The plugin to test equivalency against. - * @return boolean True if the testPlugin is equivalent to this plugin. - */ - public boolean isEquivalent(final Plugin testPlugin) { - if (testPlugin != null && testPlugin instanceof SocketHubReceiver) { - SocketHubReceiver sReceiver = (SocketHubReceiver) testPlugin; - - return (port == sReceiver.getPort() - && host.equals(sReceiver.getHost()) - && reconnectionDelay == sReceiver.getReconnectionDelay() - && super.isEquivalent(testPlugin)); - } - return false; - } - - /** - Returns true if this receiver is active. - @return true if receiver is active - */ - public synchronized boolean isActive() { - return active; - } - - /** - Sets the flag to indicate if receiver is active or not. - @param b new value - */ - protected synchronized void setActive(final boolean b) { - active = b; - } - - /** - Starts the SocketReceiver with the current options. */ - public void activateOptions() { - if (!isActive()) { - setActive(true); - fireConnector(false); - } - } - - /** - Called when the receiver should be stopped. Closes the socket */ - public synchronized void shutdown() { - // mark this as no longer running - active = false; - - // close the socket - try { - if (socket != null) { - socket.close(); - } - } catch (Exception e) { - // ignore for now - } - socket = null; - - // stop the connector - if (connector != null) { - connector.interrupted = true; - connector = null; // allow gc - } - } - - /** - Listen for a socketClosedEvent from the SocketNode. Reopen the - socket if this receiver is still active. - @param e exception not used. - */ - public void socketClosedEvent(final Exception e) { - // we clear the connector object here - // so that it actually does reconnect if the - // remote socket dies. - connector = null; - fireConnector(true); - } - - /** - * Fire connectors. - * @param isReconnect true if reconnect. - */ - private synchronized void fireConnector(final boolean isReconnect) { - if (active && connector == null) { - getLogger().debug("Starting a new connector thread."); - connector = new Connector(isReconnect); - connector.setDaemon(true); - connector.setPriority(Thread.MIN_PRIORITY); - connector.start(); - } - } - - /** - * Set socket. - * @param newSocket new value for socket. - */ - private synchronized void setSocket(final Socket newSocket) { - connector = null; - socket = newSocket; - SocketNode node = new SocketNode(socket, this); - node.addSocketNodeEventListener(this); - - synchronized (listenerList) { - for (Iterator iter = listenerList.iterator(); iter.hasNext();) { - SocketNodeEventListener listener = - (SocketNodeEventListener) iter.next(); - node.addSocketNodeEventListener(listener); - } - } - new Thread(node).start(); - } - - /** - The Connector will reconnect when the server becomes available - again. It does this by attempting to open a new connection every - reconnectionDelay milliseconds. - -

    It stops trying whenever a connection is established. It will - restart to try reconnect to the server when previpously open - connection is droppped. - - @author Ceki Gülcü - */ - private final class Connector extends Thread { - - /** - * Interruption status. - */ - boolean interrupted = false; - /** - * If true, then delay on next iteration. - */ - boolean doDelay; - - /** - * Create new instance. - * @param isReconnect true if reconnecting. - */ - public Connector(final boolean isReconnect) { - super(); - doDelay = isReconnect; - } - - /** - * Attempt to connect until interrupted. - */ - public void run() { - while (!interrupted) { - try { - if (doDelay) { - getLogger().debug("waiting for " + reconnectionDelay - + " milliseconds before reconnecting."); - sleep(reconnectionDelay); - } - doDelay = true; - getLogger().debug("Attempting connection to " + host); - Socket s = new Socket(host, port); - setSocket(s); - getLogger().debug( - "Connection established. Exiting connector thread."); - break; - } catch (InterruptedException e) { - getLogger().debug("Connector interrupted. Leaving loop."); - return; - } catch (java.net.ConnectException e) { - getLogger().debug("Remote host {} refused connection.", host); - } catch (IOException e) { - getLogger().debug("Could not connect to {}. Exception is {}.", - host, e); - } - } - } - } - - /** - * This method does nothing. - * @param remoteInfo remote info. - */ - public void socketOpened(final String remoteInfo) { - - // This method does nothing. - } - -} diff --git a/src/main/java/org/apache/log4j/net/SocketHubReceiverBeanInfo.java b/src/main/java/org/apache/log4j/net/SocketHubReceiverBeanInfo.java deleted file mode 100644 index 7b58524a9c..0000000000 --- a/src/main/java/org/apache/log4j/net/SocketHubReceiverBeanInfo.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.net; - -import java.beans.PropertyDescriptor; -import java.beans.SimpleBeanInfo; - - -/** - * BeanInfo class for the SocketHubReceiver. - * - * @author Paul Smith - * - */ -public class SocketHubReceiverBeanInfo extends SimpleBeanInfo { - - /* (non-Javadoc) - * @see java.beans.BeanInfo#getPropertyDescriptors() - */ - public PropertyDescriptor[] getPropertyDescriptors() { - - try { - - return new PropertyDescriptor[] { - new PropertyDescriptor("name", SocketHubReceiver.class), - new PropertyDescriptor("host", SocketHubReceiver.class), - new PropertyDescriptor("port", SocketHubReceiver.class), - new PropertyDescriptor("threshold", SocketHubReceiver.class), - new PropertyDescriptor("reconnectionDelay", - SocketHubReceiver.class), - }; - } catch (Exception e) { - } - - return null; - } -} diff --git a/src/main/java/org/apache/log4j/net/SocketNode.java b/src/main/java/org/apache/log4j/net/SocketNode.java index e8adac487d..e977f1333a 100644 --- a/src/main/java/org/apache/log4j/net/SocketNode.java +++ b/src/main/java/org/apache/log4j/net/SocketNode.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,21 +19,14 @@ import java.io.BufferedInputStream; import java.io.IOException; +import java.io.InterruptedIOException; import java.io.ObjectInputStream; import java.net.Socket; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; import org.apache.log4j.Logger; -import org.apache.log4j.plugins.Pauseable; -import org.apache.log4j.plugins.Receiver; -import org.apache.log4j.spi.ComponentBase; import org.apache.log4j.spi.LoggerRepository; import org.apache.log4j.spi.LoggingEvent; - // Contributors: Moses Hohman /** @@ -45,224 +38,87 @@ local file and also resent them to a second socket node. @author Ceki Gülcü - @author Paul Smith (psmith@apache.org) @since 0.8.4 */ -public class SocketNode extends ComponentBase implements Runnable, Pauseable { +public class SocketNode implements Runnable { - /** - * Paused state. - */ - private boolean paused; - /** - * Socket. - */ - private Socket socket; - /** - * Receiver. - */ - private Receiver receiver; - /** - * List of listeners. - */ - private List listenerList = Collections.synchronizedList(new ArrayList()); + Socket socket; + LoggerRepository hierarchy; + ObjectInputStream ois; - /** - Constructor for socket and logger repository. - @param s socket - @param hierarchy logger repository - */ - public SocketNode(final Socket s, - final LoggerRepository hierarchy) { - super(); - this.socket = s; - this.repository = hierarchy; - } + static Logger logger = Logger.getLogger(SocketNode.class); - /** - Constructor for socket and receiver. - @param s socket - @param r receiver - */ - public SocketNode(final Socket s, final Receiver r) { - super(); - this.socket = s; - this.receiver = r; - } - - /** - * Set the event listener on this node. - * - * @deprecated Now supports mutliple listeners, this method - * simply invokes the removeSocketNodeEventListener() to remove - * the listener, and then readds it. - * @param l listener - */ - public void setListener(final SocketNodeEventListener l) { - removeSocketNodeEventListener(l); - addSocketNodeEventListener(l); - } - - /** - * Adds the listener to the list of listeners to be notified of the - * respective event. - * @param listener the listener to add to the list - */ - public void addSocketNodeEventListener( - final SocketNodeEventListener listener) { - listenerList.add(listener); + public SocketNode(Socket socket, LoggerRepository hierarchy) { + this.socket = socket; + this.hierarchy = hierarchy; + try { + ois = new ObjectInputStream( + new BufferedInputStream(socket.getInputStream())); + } catch(InterruptedIOException e) { + Thread.currentThread().interrupt(); + logger.error("Could not open ObjectInputStream to "+socket, e); + } catch(IOException e) { + logger.error("Could not open ObjectInputStream to "+socket, e); + } catch(RuntimeException e) { + logger.error("Could not open ObjectInputStream to "+socket, e); + } } - /** - * Removes the registered Listener from this instances list of - * listeners. If the listener has not been registered, then invoking - * this method has no effect. - * - * @param listener the SocketNodeEventListener to remove - */ - public void removeSocketNodeEventListener( - final SocketNodeEventListener listener) { - listenerList.remove(listener); - } + //public + //void finalize() { + //System.err.println("-------------------------Finalize called"); + // System.err.flush(); + //} - /** - * Deserialize events from socket until interrupted. - */ public void run() { LoggingEvent event; Logger remoteLogger; - Exception listenerException = null; - ObjectInputStream ois = null; try { - ois = - new ObjectInputStream( - new BufferedInputStream(socket.getInputStream())); - } catch (Exception e) { - ois = null; - listenerException = e; - getLogger().error("Exception opening ObjectInputStream to " + socket, e); - } - - if (ois != null) { - String remoteInfo = - socket.getInetAddress().getHostName() + ":" + socket.getPort(); - - /** - * notify the listener that the socket has been - * opened and this SocketNode is ready and waiting - */ - fireSocketOpened(remoteInfo); - - try { - while (true) { - // read an event from the wire - event = (LoggingEvent) ois.readObject(); - - // store the known remote info in an event property - event.setProperty("log4j.remoteSourceInfo", remoteInfo); - - // if configured with a receiver, tell it to post the event - if (!isPaused()) { - if ((receiver != null)) { - receiver.doPost(event); - - // else post it via the hierarchy - } else { - // get a logger from the hierarchy. The name of the logger - // is taken to be the name contained in the event. - remoteLogger = repository.getLogger(event.getLoggerName()); - - //event.logger = remoteLogger; - // apply the logger-level filter - if (event - .getLevel() - .isGreaterOrEqual(remoteLogger.getEffectiveLevel())) { - // finally log the event as if was generated locally - remoteLogger.callAppenders(event); - } - } - } else { - //we simply discard this event. - } + if (ois != null) { + while(true) { + // read an event from the wire + event = (LoggingEvent) ois.readObject(); + // get a logger from the hierarchy. The name of the logger is taken to be the name contained in the event. + remoteLogger = hierarchy.getLogger(event.getLoggerName()); + //event.logger = remoteLogger; + // apply the logger-level filter + if(event.getLevel().isGreaterOrEqual(remoteLogger.getEffectiveLevel())) { + // finally log the event as if was generated locally + remoteLogger.callAppenders(event); + } } - } catch (java.io.EOFException e) { - getLogger().info("Caught java.io.EOFException closing connection."); - listenerException = e; - } catch (java.net.SocketException e) { - getLogger().info("Caught java.net.SocketException closing connection."); - listenerException = e; - } catch (IOException e) { - getLogger().info("Caught java.io.IOException: " + e); - getLogger().info("Closing connection."); - listenerException = e; - } catch (Exception e) { - getLogger().error("Unexpected exception. Closing connection.", e); - listenerException = e; } - } - - // close the socket - try { + } catch(java.io.EOFException e) { + logger.info("Caught java.io.EOFException closing conneciton."); + } catch(java.net.SocketException e) { + logger.info("Caught java.net.SocketException closing conneciton."); + } catch(InterruptedIOException e) { + Thread.currentThread().interrupt(); + logger.info("Caught java.io.InterruptedIOException: "+e); + logger.info("Closing connection."); + } catch(IOException e) { + logger.info("Caught java.io.IOException: "+e); + logger.info("Closing connection."); + } catch(Exception e) { + logger.error("Unexpected exception. Closing conneciton.", e); + } finally { if (ois != null) { - ois.close(); + try { + ois.close(); + } catch(Exception e) { + logger.info("Could not close connection.", e); + } } - } catch (Exception e) { - //getLogger().info("Could not close connection.", e); - } - - // send event to listener, if configured - if (listenerList.size() > 0) { - fireSocketClosedEvent(listenerException); - } - } - - /** - * Notifies all registered listeners regarding the closing of the Socket. - * @param listenerException listener exception - */ - private void fireSocketClosedEvent(final Exception listenerException) { - synchronized (listenerList) { - for (Iterator iter = listenerList.iterator(); iter.hasNext();) { - SocketNodeEventListener snel = - (SocketNodeEventListener) iter.next(); - if (snel != null) { - snel.socketClosedEvent(listenerException); - } - } - } - } - - /** - * Notifies all registered listeners regarding the opening of a Socket. - * @param remoteInfo remote info - */ - private void fireSocketOpened(final String remoteInfo) { - synchronized (listenerList) { - for (Iterator iter = listenerList.iterator(); iter.hasNext();) { - SocketNodeEventListener snel = - (SocketNodeEventListener) iter.next(); - if (snel != null) { - snel.socketOpened(remoteInfo); - } + if (socket != null) { + try { + socket.close(); + } catch(InterruptedIOException e) { + Thread.currentThread().interrupt(); + } catch(IOException ex) { } + } } } - - /** - * Sets if node is paused. - * @param b new value - */ - public void setPaused(final boolean b) { - this.paused = b; - } - - /** - * Get if node is paused. - * @return true if pause. - */ - public boolean isPaused() { - return this.paused; - } } diff --git a/src/main/java/org/apache/log4j/net/SocketNodeEventListener.java b/src/main/java/org/apache/log4j/net/SocketNodeEventListener.java deleted file mode 100644 index c50c75db59..0000000000 --- a/src/main/java/org/apache/log4j/net/SocketNodeEventListener.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.net; - -import java.util.EventListener; - -/** - Interface used to listen for {@link SocketNode} related - events. Clients register an instance of the interface and the - instance is called back when the various events occur. - - @author Mark Womack - @author Paul Smith (psmith@apache.org) - @since 1.3 -*/ -public interface SocketNodeEventListener extends EventListener { - - /** - * Called when the SocketNode is created and begins awaiting data. - * @param remoteInfo remote info - */ - void socketOpened(String remoteInfo); - - /** - Called when the socket the node was given has been closed. - @param e exception - */ - void socketClosedEvent(Exception e); -} diff --git a/src/main/java/org/apache/log4j/net/SocketReceiver.java b/src/main/java/org/apache/log4j/net/SocketReceiver.java deleted file mode 100644 index 284a8e0de8..0000000000 --- a/src/main/java/org/apache/log4j/net/SocketReceiver.java +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.net; - -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Vector; - -import org.apache.log4j.plugins.Pauseable; -import org.apache.log4j.plugins.Plugin; -import org.apache.log4j.plugins.Receiver; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggingEvent; - - -/** - SocketReceiver receives a remote logging event on a configured - socket and "posts" it to a LoggerRepository as if the event was - generated locally. This class is designed to receive events from - the SocketAppender class (or classes that send compatible events). - -

    Once the event has been "posted", it will be handled by the - appenders currently configured in the LoggerRespository. - - @author Mark Womack - @author Scott Deboy (sdeboy@apache.org) - @author Paul Smith (psmith@apache.org) - @since 1.3 -*/ -public class SocketReceiver extends Receiver implements Runnable, PortBased, - Pauseable { - /** - * socket map. - */ - private Map socketMap = new HashMap(); - /** - * Paused. - */ - private boolean paused; - /** - * Thread. - */ - private Thread rThread; - /** - * Port. - */ - protected int port; - /** - * Server socket. - */ - private ServerSocket serverSocket; - /** - * Socket list. - */ - private Vector socketList = new Vector(); - /** - * Listener. - */ - private SocketNodeEventListener listener = null; - /** - * Listeners. - */ - private List listenerList = Collections.synchronizedList(new ArrayList()); - - /** - * Create new instance. - */ - public SocketReceiver() { - super(); - } - - /** - * Create new instance. - * @param p port - */ - public SocketReceiver(final int p) { - super(); - port = p; - } - - /** - * Create new instance. - * @param p port - * @param repo logger repository - */ - public SocketReceiver(final int p, final LoggerRepository repo) { - super(); - this.port = p; - repository = repo; - } - - /** {@inheritDoc} */ - public int getPort() { - return port; - } - - /** {@inheritDoc} */ - public void setPort(final int p) { - port = p; - } - - /** - * Returns true if the receiver is the same class and they are - * configured for the same properties, and super class also considers - * them to be equivalent. This is used by PluginRegistry when determining - * if the a similarly configured receiver is being started. - * - * @param testPlugin The plugin to test equivalency against. - * @return boolean True if the testPlugin is equivalent to this plugin. - */ - public boolean isEquivalent(final Plugin testPlugin) { - if ((testPlugin != null) && testPlugin instanceof SocketReceiver) { - SocketReceiver sReceiver = (SocketReceiver) testPlugin; - - return (port == sReceiver.getPort() && super.isEquivalent(testPlugin)); - } - - return false; - } - - /** - Starts the SocketReceiver with the current options. */ - public void activateOptions() { - if (!isActive()) { - // shutdown(); - rThread = new Thread(this); - rThread.setDaemon(true); - rThread.start(); - active = true; - } - } - - /** - * Called when the receiver should be stopped. Closes the - * server socket and all of the open sockets. - */ - public synchronized void shutdown() { - getLogger().debug(getName() + " received shutdown request"); - - // mark this as no longer running - active = false; - - if (rThread != null) { - rThread.interrupt(); - rThread = null; - } - - doShutdown(); - } - - /** - * Does the actual shutting down by closing the server socket - * and any connected sockets that have been created. - */ - private synchronized void doShutdown() { - active = false; - - getLogger().debug(getName() + " doShutdown called"); - - // close the server socket - closeServerSocket(); - - // close all of the accepted sockets - closeAllAcceptedSockets(); - } - - /** - * Closes the server socket, if created. - */ - private void closeServerSocket() { - getLogger().debug("{} closing server socket", getName()); - - try { - if (serverSocket != null) { - serverSocket.close(); - } - } catch (Exception e) { - // ignore for now - } - - serverSocket = null; - } - - /** - * Closes all the connected sockets in the List. - */ - private synchronized void closeAllAcceptedSockets() { - for (int x = 0; x < socketList.size(); x++) { - try { - ((Socket) socketList.get(x)).close(); - } catch (Exception e) { - // ignore for now - } - } - - // clear member variables - socketMap.clear(); - socketList.clear(); - } - - /** - Loop, accepting new socket connections. */ - public void run() { - /** - * Ensure we start fresh. - */ - closeServerSocket(); - closeAllAcceptedSockets(); - - // start the server socket - try { - serverSocket = new ServerSocket(port); - } catch (Exception e) { - getLogger().error( - "error starting SocketReceiver (" + this.getName() - + "), receiver did not start", e); - active = false; - - return; - } - - Socket socket = null; - - try { - getLogger().debug("in run-about to enter while not interrupted loop"); - - active = true; - - while (!rThread.isInterrupted()) { - // if we have a socket, start watching it - if (socket != null) { - getLogger().debug( - "socket not null - creating and starting socketnode"); - socketList.add(socket); - - SocketNode node = new SocketNode(socket, this); - synchronized (listenerList) { - for (Iterator iter = listenerList.iterator(); - iter.hasNext();) { - SocketNodeEventListener l = - (SocketNodeEventListener) iter.next(); - node.addSocketNodeEventListener(l); - } - } - socketMap.put(socket, node); - new Thread(node).start(); - socket = null; - } - - getLogger().debug("waiting to accept socket"); - - // wait for a socket to open, then loop to start it - socket = serverSocket.accept(); - getLogger().debug("accepted socket"); - } - } catch (Exception e) { - getLogger().warn( - "exception while watching socket server in SocketReceiver (" - + this.getName() + "), stopping"); - } - - getLogger().debug("{} has exited the not interrupted loop", getName()); - - // socket not watched because we a no longer running - // so close it now. - if (socket != null) { - try { - socket.close(); - } catch (IOException e1) { - getLogger().warn("socket exception caught - socket closed"); - } - } - - getLogger().debug("{} is exiting main run loop", getName()); - } - - /** - * Returns a Vector of SocketDetail representing the IP/Domain name - * of the currently connected sockets that this receiver has - * been responsible for creating. - * @return Vector of SocketDetails - */ - public Vector getConnectedSocketDetails() { - Vector details = new Vector(socketList.size()); - - for (Enumeration enumeration = socketList.elements(); - enumeration.hasMoreElements(); - ) { - Socket socket = (Socket) enumeration.nextElement(); - details.add( - new SocketDetail(socket, (SocketNode) socketMap.get(socket))); - } - - return details; - } - - /** - * Returns the currently configured SocketNodeEventListener that - * will be automatically set for each SocketNode created. - * @return SocketNodeEventListener currently configured - * - * @deprecated This receiver now supports multiple listeners - */ - public SocketNodeEventListener getListener() { - return listener; - } - - /** - * Adds the listener to the list of listeners to be notified of the - * respective event. - * @param l the listener to add to the list - */ - public void addSocketNodeEventListener( - final SocketNodeEventListener l) { - listenerList.add(l); - } - - /** - * Removes the registered Listener from this instances list of - * listeners. If the listener has not been registered, then invoking - * this method has no effect. - * - * @param l the SocketNodeEventListener to remove - */ - public void removeSocketNodeEventListener( - final SocketNodeEventListener l) { - listenerList.remove(l); - } - - /** - * Sets the SocketNodeEventListener that will be used for each - * created SocketNode. - * @param l the listener to set on each creation of a SocketNode - * @deprecated This receiver now supports multiple listeners and - * so this method simply removes the listener (if there already) - * and readds it to the list. - * - * The passed listener will also be returned via the getListener() - * method still, but this is also deprecated - */ - public void setListener(final SocketNodeEventListener l) { - removeSocketNodeEventListener(l); - addSocketNodeEventListener(l); - this.listener = l; - } - - /** {@inheritDoc} */ - public boolean isPaused() { - return paused; - } - - /** {@inheritDoc} */ - public void setPaused(final boolean b) { - paused = b; - } - - /** - * Socket detail. - */ - public static final class SocketDetail implements AddressBased, PortBased, - Pauseable { - /** - * Address. - */ - private String address; - /** - * Port. - */ - private int port; - /** - * Socket node. - */ - private SocketNode socketNode; - - /** - * Create new instance. - * @param socket socket - * @param node socket node - */ - private SocketDetail(final Socket socket, - final SocketNode node) { - super(); - this.address = socket.getInetAddress().getHostName(); - this.port = socket.getPort(); - this.socketNode = node; - } - - /** {@inheritDoc} */ - public String getAddress() { - return address; - } - - /** {@inheritDoc} */ - public int getPort() { - return port; - } - - /** {@inheritDoc} */ - public String getName() { - return "Socket"; - } - - /** {@inheritDoc} */ - public boolean isActive() { - return true; - } - - /** {@inheritDoc} */ - public boolean isPaused() { - return socketNode.isPaused(); - } - - /** {@inheritDoc} */ - public void setPaused(final boolean b) { - socketNode.setPaused(b); - } - } - /** {@inheritDoc} */ - public void doPost(final LoggingEvent event) { - if (!isPaused()) { - super.doPost(event); - } - } - -} diff --git a/src/main/java/org/apache/log4j/net/SocketServer.java b/src/main/java/org/apache/log4j/net/SocketServer.java index 795c002851..fda74adef3 100644 --- a/src/main/java/org/apache/log4j/net/SocketServer.java +++ b/src/main/java/org/apache/log4j/net/SocketServer.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,17 +17,20 @@ package org.apache.log4j.net; -import org.apache.log4j.*; -import org.apache.log4j.spi.*; - import java.io.File; - import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; - import java.util.Hashtable; +import org.apache.log4j.Hierarchy; +import org.apache.log4j.Level; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; +import org.apache.log4j.spi.LoggerRepository; +import org.apache.log4j.spi.RootLogger; + /** A {@link SocketNode} based server that uses a different hierarchy @@ -70,7 +73,7 @@

    Currently, the hierarchy that will be used for a given request depends on the IP address of the client host. For example, two - separate applicatons running on the same host and logging to the + separate applications running on the same host and logging to the same server will share the same hierarchy. This is perfectly safe except that it might not provide the right amount of independence between applications. The SocketServer is intended @@ -81,10 +84,13 @@ @author Ceki Gülcü @since 1.0 */ -public class SocketServer { + +public class SocketServer { + static String GENERIC = "generic"; static String CONFIG_FILE_EXT = ".lcf"; - static final Logger logger = Logger.getLogger(SocketServer.class); + + static Logger cat = Logger.getLogger(SocketServer.class); static SocketServer server; static int port; @@ -93,126 +99,115 @@ public class SocketServer { LoggerRepository genericHierarchy; File dir; - public SocketServer(File directory) { - this.dir = directory; - hierarchyMap = new Hashtable(11); - } - - public static void main(String[] argv) { - if (argv.length == 3) { - init(argv[0], argv[1], argv[2]); + public + static + void main(String argv[]) { + if(argv.length == 3) { + init(argv[0], argv[1], argv[2]); } else { - usage("Wrong number of arguments."); + usage("Wrong number of arguments."); } try { - logger.info("Listening on port " + port); - + cat.info("Listening on port " + port); ServerSocket serverSocket = new ServerSocket(port); - - while (true) { - logger.info("Waiting to accept a new client."); - - Socket socket = serverSocket.accept(); - InetAddress inetAddress = socket.getInetAddress(); - logger.info("Connected to client at " + inetAddress); - - LoggerRepository h = - (LoggerRepository) server.hierarchyMap.get(inetAddress); - - if (h == null) { - h = server.configureHierarchy(inetAddress); - } - - logger.info("Starting new socket node."); - new Thread(new SocketNode(socket, h)).start(); + while(true) { + cat.info("Waiting to accept a new client."); + Socket socket = serverSocket.accept(); + InetAddress inetAddress = socket.getInetAddress(); + cat.info("Connected to client at " + inetAddress); + + LoggerRepository h = (LoggerRepository) server.hierarchyMap.get(inetAddress); + if(h == null) { + h = server.configureHierarchy(inetAddress); + } + + cat.info("Starting new socket node."); + new Thread(new SocketNode(socket, h)).start(); } - } catch (Exception e) { + } + catch(Exception e) { e.printStackTrace(); } } - static void usage(String msg) { + + static + void usage(String msg) { System.err.println(msg); System.err.println( - "Usage: java " + SocketServer.class.getName() - + " port configFile directory"); + "Usage: java " +SocketServer.class.getName() + " port configFile directory"); System.exit(1); } - static void init(String portStr, String configFile, String dirStr) { + static + void init(String portStr, String configFile, String dirStr) { try { port = Integer.parseInt(portStr); - } catch (java.lang.NumberFormatException e) { + } + catch(java.lang.NumberFormatException e) { e.printStackTrace(); - usage("Could not interpret port number [" + portStr + "]."); + usage("Could not interpret port number ["+ portStr +"]."); } PropertyConfigurator.configure(configFile); File dir = new File(dirStr); - - if (!dir.isDirectory()) { - usage("[" + dirStr + "] is not a directory."); + if(!dir.isDirectory()) { + usage("["+dirStr+"] is not a directory."); } - server = new SocketServer(dir); } + public + SocketServer(File directory) { + this.dir = directory; + hierarchyMap = new Hashtable(11); + } + // This method assumes that there is no hiearchy for inetAddress // yet. It will configure one and return it. LoggerRepository configureHierarchy(InetAddress inetAddress) { - logger.info("Locating configuration file for " + inetAddress); - + cat.info("Locating configuration file for "+inetAddress); // We assume that the toSting method of InetAddress returns is in // the format hostname/d1.d2.d3.d4 e.g. torino/192.168.1.1 String s = inetAddress.toString(); int i = s.indexOf("/"); - - if (i == -1) { - logger.warn( - "Could not parse the inetAddress [" + inetAddress - + "]. Using default hierarchy."); - + if(i == -1) { + cat.warn("Could not parse the inetAddress ["+inetAddress+ + "]. Using default hierarchy."); return genericHierarchy(); } else { String key = s.substring(0, i); - File configFile = new File(dir, key + CONFIG_FILE_EXT); + File configFile = new File(dir, key+CONFIG_FILE_EXT); + if(configFile.exists()) { + Hierarchy h = new Hierarchy(new RootLogger(Level.DEBUG)); + hierarchyMap.put(inetAddress, h); - if (configFile.exists()) { - Hierarchy h = new Hierarchy(new RootLogger(Level.DEBUG)); - hierarchyMap.put(inetAddress, h); + new PropertyConfigurator().doConfigure(configFile.getAbsolutePath(), h); - new PropertyConfigurator().doConfigure( - configFile.getAbsolutePath(), h); - - return h; + return h; } else { - logger.warn("Could not find config file [" + configFile + "]."); - - return genericHierarchy(); + cat.warn("Could not find config file ["+configFile+"]."); + return genericHierarchy(); } } } - LoggerRepository genericHierarchy() { - if (genericHierarchy == null) { - File f = new File(dir, GENERIC + CONFIG_FILE_EXT); - - if (f.exists()) { - genericHierarchy = new Hierarchy(new RootLogger(Level.DEBUG)); - new PropertyConfigurator().doConfigure( - f.getAbsolutePath(), genericHierarchy); + LoggerRepository genericHierarchy() { + if(genericHierarchy == null) { + File f = new File(dir, GENERIC+CONFIG_FILE_EXT); + if(f.exists()) { + genericHierarchy = new Hierarchy(new RootLogger(Level.DEBUG)); + new PropertyConfigurator().doConfigure(f.getAbsolutePath(), genericHierarchy); } else { - logger.warn( - "Could not find config file [" + f - + "]. Will use the default hierarchy."); - genericHierarchy = LogManager.getLoggerRepository(); + cat.warn("Could not find config file ["+f+ + "]. Will use the default hierarchy."); + genericHierarchy = LogManager.getLoggerRepository(); } } - return genericHierarchy; } } diff --git a/src/main/java/org/apache/log4j/net/SyslogAppender.java b/src/main/java/org/apache/log4j/net/SyslogAppender.java index ddbd5719b5..b0246453c9 100644 --- a/src/main/java/org/apache/log4j/net/SyslogAppender.java +++ b/src/main/java/org/apache/log4j/net/SyslogAppender.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,400 +17,586 @@ package org.apache.log4j.net; -import org.apache.log4j.Layout; -import org.apache.log4j.Level; -import org.apache.log4j.WriterAppender; -import org.apache.log4j.helpers.SyslogWriter; -import org.apache.log4j.spi.LoggingEvent; - import java.io.IOException; - import java.net.InetAddress; import java.net.UnknownHostException; - -import java.text.DateFormatSymbols; -import java.text.FieldPosition; import java.text.SimpleDateFormat; - import java.util.Date; import java.util.Locale; +import java.util.regex.Pattern; +import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.Layout; +import org.apache.log4j.helpers.SyslogQuietWriter; +import org.apache.log4j.helpers.SyslogWriter; +import org.apache.log4j.spi.LoggingEvent; // Contributors: Yves Bossel // Christopher Taylor /** - * Implements an RFC 3164 compliant agent to send log messages to a remote - * syslog daemon. - * - * @author Ceki Gülcü - * @author Anders Kristensen - * @author Hermod Opstvedt - * @author Curt Arnold - */ -public class SyslogAppender extends WriterAppender { - // The following constants are extracted from a syslog.h file - // copyrighted by the Regents of the University of California - // I hope nobody at Berkley gets offended. - - /** Kernel messages */ - final static public int LOG_KERN = 0; - /** Random user-level messages */ - final static public int LOG_USER = 1<<3; - /** Mail system */ - final static public int LOG_MAIL = 2<<3; - /** System daemons */ - final static public int LOG_DAEMON = 3<<3; - /** security/authorization messages */ - final static public int LOG_AUTH = 4<<3; - /** messages generated internally by syslogd */ - final static public int LOG_SYSLOG = 5<<3; - - /** line printer subsystem */ - final static public int LOG_LPR = 6<<3; - /** network news subsystem */ - final static public int LOG_NEWS = 7<<3; - /** UUCP subsystem */ - final static public int LOG_UUCP = 8<<3; - /** clock daemon */ - final static public int LOG_CRON = 9<<3; - /** security/authorization messages (private) */ - final static public int LOG_AUTHPRIV = 10<<3; - /** ftp daemon */ - final static public int LOG_FTP = 11<<3; - - // other codes through 15 reserved for system use - /** reserved for local use */ - final static public int LOG_LOCAL0 = 16<<3; - /** reserved for local use */ - final static public int LOG_LOCAL1 = 17<<3; - /** reserved for local use */ - final static public int LOG_LOCAL2 = 18<<3; - /** reserved for local use */ - final static public int LOG_LOCAL3 = 19<<3; - /** reserved for local use */ - final static public int LOG_LOCAL4 = 20<<3; - /** reserved for local use */ - final static public int LOG_LOCAL5 = 21<<3; - /** reserved for local use */ - final static public int LOG_LOCAL6 = 22<<3; - /** reserved for local use*/ - final static public int LOG_LOCAL7 = 23<<3; + Use SyslogAppender to send log messages to a remote syslog daemon. - /** - * Names of facilities. - */ - private static final String[] FACILITIES = - new String[] { - "kern", "user", "mail", "daemon", - "auth", "syslog", "lpr", "news", - "uucp", "cron", "authpriv","ftp", - null, null, null, null, - "local0", "local1", "local2", "local3", - "local4", "local5", "local6", "local7" - - }; + @author Ceki Gülcü + @author Anders Kristensen + */ +public class SyslogAppender extends AppenderSkeleton { + // The following constants are extracted from a syslog.h file + // copyrighted by the Regents of the University of California + // I hope nobody at Berkley gets offended. + /** + * Maximum length of a TAG string. + */ + private static final int MAX_TAG_LEN = 32; + + /** Kernel messages */ + final static public int LOG_KERN = 0; + /** Random user-level messages */ + final static public int LOG_USER = 1<<3; + /** Mail system */ + final static public int LOG_MAIL = 2<<3; + /** System daemons */ + final static public int LOG_DAEMON = 3<<3; + /** security/authorization messages */ + final static public int LOG_AUTH = 4<<3; + /** messages generated internally by syslogd */ + final static public int LOG_SYSLOG = 5<<3; + + /** line printer subsystem */ + final static public int LOG_LPR = 6<<3; + /** network news subsystem */ + final static public int LOG_NEWS = 7<<3; + /** UUCP subsystem */ + final static public int LOG_UUCP = 8<<3; + /** clock daemon */ + final static public int LOG_CRON = 9<<3; + /** security/authorization messages (private) */ + final static public int LOG_AUTHPRIV = 10<<3; + /** ftp daemon */ + final static public int LOG_FTP = 11<<3; + + // other codes through 15 reserved for system use + /** reserved for local use */ + final static public int LOG_LOCAL0 = 16<<3; + /** reserved for local use */ + final static public int LOG_LOCAL1 = 17<<3; + /** reserved for local use */ + final static public int LOG_LOCAL2 = 18<<3; + /** reserved for local use */ + final static public int LOG_LOCAL3 = 19<<3; + /** reserved for local use */ + final static public int LOG_LOCAL4 = 20<<3; + /** reserved for local use */ + final static public int LOG_LOCAL5 = 21<<3; + /** reserved for local use */ + final static public int LOG_LOCAL6 = 22<<3; + /** reserved for local use*/ + final static public int LOG_LOCAL7 = 23<<3; protected static final int SYSLOG_HOST_OI = 0; protected static final int FACILITY_OI = 1; + static final String TAB = " "; + + static final Pattern NOT_ALPHANUM = Pattern.compile("[^\\p{Alnum}]"); + + // Have LOG_USER as default int syslogFacility = LOG_USER; - String facilityStr = "user"; - /** - * In log4j 1.2, controlled whether facility name was included in message, - * but has no effect in current code. - * @deprecated since 1.3 - */ + String facilityStr; boolean facilityPrinting = false; - String localHostname; + //SyslogTracerPrintWriter stp; + SyslogQuietWriter sqw; String syslogHost; - // We must use US locale to get the correct month abreviation - private SimpleDateFormat sdf = - new SimpleDateFormat("MMM dd hh:mm:ss", new DateFormatSymbols(Locale.US)); + /** + * If true, the appender will generate the HEADER (timestamp and host name) + * part of the syslog packet. + * @since 1.2.15 + */ + private boolean header = false; + + /** + * The TAG part of the syslog message. + * + * @since 1.2.18 + */ + private String tag = null; + + /** + * Date format used if header = true. + * @since 1.2.15 + */ + private final SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd HH:mm:ss ", Locale.ENGLISH); + + /** + * Host name used to identify messages from this appender. + * @since 1.2.15 + */ + private String localHostname; - public SyslogAppender() { - } + /** + * Set to true after the header of the layout has been sent or if it has none. + */ + private boolean layoutHeaderChecked = false; public - SyslogAppender(final Layout layout, final int syslogFacility) { - this.layout = layout; - this.syslogFacility = syslogFacility; - String newFacilityStr = getFacilityString(syslogFacility); - if (newFacilityStr != null) { - facilityStr = newFacilityStr; - } + SyslogAppender() { + this.initSyslogFacilityStr(); } - public - SyslogAppender(final Layout layout, final String syslogHost, final int syslogFacility) { - this(layout, syslogFacility); - setSyslogHost(syslogHost); - } + public + SyslogAppender(Layout layout, int syslogFacility) { + this.layout = layout; + this.syslogFacility = syslogFacility; + this.initSyslogFacilityStr(); + } + public + SyslogAppender(Layout layout, String syslogHost, int syslogFacility) { + this(layout, syslogFacility); + setSyslogHost(syslogHost); + } /** - * This method gets the network name of the machine we are running on. - * Returns "UNKNOWN_HOST" in the unlikely case where the host name cannot be - * found. - * @return String + Release any resources held by this SyslogAppender. + + @since 0.8.4 */ - public String getLocalHostname() { - try { - InetAddress addr = InetAddress.getLocalHost(); - return addr.getHostName(); - } catch (UnknownHostException uhe) { - getLogger().error( - "Could not determine local host name for SyslogAppender" + "named [" - + name + "].", uhe); - return "UNKNOWN_HOST"; + synchronized + public + void close() { + closed = true; + if (sqw != null) { + try { + if (layoutHeaderChecked && layout != null && layout.getFooter() != null) { + sendLayoutMessage(layout.getFooter()); + } + sqw.close(); + sqw = null; + } catch(java.io.InterruptedIOException e) { + Thread.currentThread().interrupt(); + sqw = null; + } catch(IOException e) { + sqw = null; + } } } - /** - * Returns the specified syslog facility as a lower-case String, - * e.g. "kern", "user", etc. - * @deprecated since 1.3 - */ - public - static - String getFacilityString(final int syslogFacility) { - String facilityStr = null; - if((syslogFacility & 0x7) == 0) { - int index = syslogFacility >> 3; - if(index >= 0 && index < FACILITIES.length) { - facilityStr = FACILITIES[index]; - } - } - return facilityStr; - } + private + void initSyslogFacilityStr() { + facilityStr = getFacilityString(this.syslogFacility); + if (facilityStr == null) { + System.err.println("\"" + syslogFacility + + "\" is an unknown syslog facility. Defaulting to \"USER\"."); + this.syslogFacility = LOG_USER; + facilityStr = "user:"; + } else { + facilityStr += ":"; + } + } /** - * Returns the integer value corresponding to the named syslog facility, - * or -1 if it couldn't be recognized. - * - * */ - public static int getFacility(final String facilityStr) { - int code = -1; - if (facilityStr != null) { - for(int i = 0; i < FACILITIES.length; i++) { - if (facilityStr.equalsIgnoreCase(FACILITIES[i])) { - code = i << 3; - break; - } - } + Returns the specified syslog facility as a lower-case String, + e.g. "kern", "user", etc. + */ + public + static + String getFacilityString(int syslogFacility) { + switch(syslogFacility) { + case LOG_KERN: return "kern"; + case LOG_USER: return "user"; + case LOG_MAIL: return "mail"; + case LOG_DAEMON: return "daemon"; + case LOG_AUTH: return "auth"; + case LOG_SYSLOG: return "syslog"; + case LOG_LPR: return "lpr"; + case LOG_NEWS: return "news"; + case LOG_UUCP: return "uucp"; + case LOG_CRON: return "cron"; + case LOG_AUTHPRIV: return "authpriv"; + case LOG_FTP: return "ftp"; + case LOG_LOCAL0: return "local0"; + case LOG_LOCAL1: return "local1"; + case LOG_LOCAL2: return "local2"; + case LOG_LOCAL3: return "local3"; + case LOG_LOCAL4: return "local4"; + case LOG_LOCAL5: return "local5"; + case LOG_LOCAL6: return "local6"; + case LOG_LOCAL7: return "local7"; + default: return null; } - return code; } /** - * This method returns immediately as options are activated when they are set. - * */ - public void activateOptions() { - if (facilityStr == null) { - String errMsg = - "The Facility option must be set for SyslogAppender named [" + name - + "]."; - getLogger().error(errMsg); - throw new IllegalStateException(errMsg); + Returns the integer value corresponding to the named syslog + facility, or -1 if it couldn't be recognized. + + @param facilityName one of the strings KERN, USER, MAIL, DAEMON, + AUTH, SYSLOG, LPR, NEWS, UUCP, CRON, AUTHPRIV, FTP, LOCAL0, + LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. + The matching is case-insensitive. + + @since 1.1 + */ + public + static + int getFacility(String facilityName) { + if(facilityName != null) { + facilityName = facilityName.trim(); } - facilityStr = facilityStr.trim(); - getLogger().debug("Facility string set to be {}.", facilityStr); - syslogFacility = getFacility(facilityStr); - getLogger().debug("Facility set to be "+ syslogFacility); - - if (syslogFacility == -1) { - String errMsg = - "Unrecognized Facility option \"" + facilityStr - + "\" SyslogAppender named [" + name + "]."; - getLogger().error(errMsg); - throw new IllegalStateException(errMsg); + if("KERN".equalsIgnoreCase(facilityName)) { + return LOG_KERN; + } else if("USER".equalsIgnoreCase(facilityName)) { + return LOG_USER; + } else if("MAIL".equalsIgnoreCase(facilityName)) { + return LOG_MAIL; + } else if("DAEMON".equalsIgnoreCase(facilityName)) { + return LOG_DAEMON; + } else if("AUTH".equalsIgnoreCase(facilityName)) { + return LOG_AUTH; + } else if("SYSLOG".equalsIgnoreCase(facilityName)) { + return LOG_SYSLOG; + } else if("LPR".equalsIgnoreCase(facilityName)) { + return LOG_LPR; + } else if("NEWS".equalsIgnoreCase(facilityName)) { + return LOG_NEWS; + } else if("UUCP".equalsIgnoreCase(facilityName)) { + return LOG_UUCP; + } else if("CRON".equalsIgnoreCase(facilityName)) { + return LOG_CRON; + } else if("AUTHPRIV".equalsIgnoreCase(facilityName)) { + return LOG_AUTHPRIV; + } else if("FTP".equalsIgnoreCase(facilityName)) { + return LOG_FTP; + } else if("LOCAL0".equalsIgnoreCase(facilityName)) { + return LOG_LOCAL0; + } else if("LOCAL1".equalsIgnoreCase(facilityName)) { + return LOG_LOCAL1; + } else if("LOCAL2".equalsIgnoreCase(facilityName)) { + return LOG_LOCAL2; + } else if("LOCAL3".equalsIgnoreCase(facilityName)) { + return LOG_LOCAL3; + } else if("LOCAL4".equalsIgnoreCase(facilityName)) { + return LOG_LOCAL4; + } else if("LOCAL5".equalsIgnoreCase(facilityName)) { + return LOG_LOCAL5; + } else if("LOCAL6".equalsIgnoreCase(facilityName)) { + return LOG_LOCAL6; + } else if("LOCAL7".equalsIgnoreCase(facilityName)) { + return LOG_LOCAL7; + } else { + return -1; } + } + + + private void splitPacket(final String header, final String packet) { + int byteCount = packet.getBytes().length; + // + // if packet is less than RFC 3164 limit + // of 1024 bytes, then write it + // (must allow for up 5to 5 characters in the PRI section + // added by SyslogQuietWriter) + if (byteCount <= 1019) { + sqw.write(packet); + } else { + int split = header.length() + (packet.length() - header.length())/2; + splitPacket(header, packet.substring(0, split) + "..."); + splitPacket(header, header + "..." + packet.substring(split)); + } + } + + public + void append(LoggingEvent event) { - if (syslogHost == null) { - String errMsg = - "No syslog host is set for SyslogAppender named \"" + this.name - + "\"."; - getLogger().error(errMsg); - throw new IllegalStateException(errMsg); + if(!isAsSevereAsThreshold(event.getLevel())) { + return; + } + + // We must not attempt to append if sqw is null. + if(sqw == null) { + errorHandler.error("No syslog host is set for SyslogAppedender named \""+ + this.name+"\"."); + return; } + if (!layoutHeaderChecked) { + if (layout != null && layout.getHeader() != null) { + sendLayoutMessage(layout.getHeader()); + } + layoutHeaderChecked = true; + } + + String hdr = getPacketHeader(event.timeStamp); + String packet; if (layout == null) { - String errMsg = - "No Layout is set for SyslogAppender named \"" + this.name - + "\"."; - getLogger().error(errMsg); - throw new IllegalStateException(errMsg); + packet = String.valueOf(event.getMessage()); + } else { + packet = layout.format(event); + } + if(facilityPrinting || hdr.length() > 0) { + StringBuffer buf = new StringBuffer(hdr); + if(facilityPrinting) { + buf.append(facilityStr); + } + buf.append(packet); + packet = buf.toString(); + } + + sqw.setLevel(event.getLevel().getSyslogEquivalent()); + // + // if message has a remote likelihood of exceeding 1024 bytes + // when encoded, consider splitting message into multiple packets + if (packet.length() > 256) { + splitPacket(hdr, packet); + } else { + sqw.write(packet); } - - localHostname = getLocalHostname(); - SyslogWriter sw = new SyslogWriter(syslogHost); - setWriter(sw); - super.activateOptions(); + if (layout == null || layout.ignoresThrowable()) { + String[] s = event.getThrowableStrRep(); + if (s != null) { + for(int i = 0; i < s.length; i++) { + if (s[i].startsWith("\t")) { + sqw.write(hdr+TAB+s[i].substring(1)); + } else { + sqw.write(hdr+s[i]); + } + } + } + } } - /** - The SyslogAppender requires a layout. Hence, this method returns - true. + /** + This method returns immediately as options are activated when they + are set. + */ + public + void activateOptions() { + if (header) { + getLocalHostname(); + } + if (layout != null && layout.getHeader() != null) { + sendLayoutMessage(layout.getHeader()); + } + layoutHeaderChecked = true; + } - @since 0.8.4 */ - public - boolean requiresLayout() { - return true; - } + /** + The SyslogAppender requires a layout. Hence, this method returns + true. + @since 0.8.4 */ + public + boolean requiresLayout() { + return true; + } /** - * The SyslogHost option is the name of the the syslog host where log - * output should go. A non-default port can be specified by - * appending a colon and port number to a host name, - * an IPv4 address or an IPv6 address enclosed in square brackets. - * - * WARNING If the SyslogHost is not set, then this appender will fail. + The SyslogHost option is the name of the the syslog host + where log output should go. A non-default port can be specified by + appending a colon and port number to a host name, + an IPv4 address or an IPv6 address enclosed in square brackets. + + WARNING If the SyslogHost is not set, then this appender + will fail. */ - public void setSyslogHost(String syslogHost) { + public + void setSyslogHost(final String syslogHost) { + this.sqw = new SyslogQuietWriter(new SyslogWriter(syslogHost), + syslogFacility, errorHandler); + //this.stp = new SyslogTracerPrintWriter(sqw); this.syslogHost = syslogHost; } /** - * Returns the value of the SyslogHost option. + Returns the value of the SyslogHost option. */ - public String getSyslogHost() { + public + String getSyslogHost() { return syslogHost; } /** - * Set the syslog facility. This is the Facility option. - * - *

    The facility parameter must be one of the strings KERN, - * USER, MAIL, DAEMON, AUTH, SYSLOG, LPR, NEWS, UUCP, CRON, AUTHPRIV, FTP, - * NTP, AUDIT, ALERT, CLOCK, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, - * LOCAL6, LOCAL7. Case is not important. - * - * See RFC 3164 for more information about the - * Facility option. - * */ - public void setFacility(final String facility) { - if (facility != null) { - syslogFacility = getFacility(facility); - if (syslogFacility == -1) { - System.err.println("["+facility + - "] is an unknown syslog facility. Defaulting to [USER]."); - syslogFacility = LOG_USER; - } - facilityStr = getFacilityString(syslogFacility); + Set the syslog facility. This is the Facility option. + +

    The facilityName parameter must be one of the + strings KERN, USER, MAIL, DAEMON, AUTH, SYSLOG, LPR, NEWS, UUCP, + CRON, AUTHPRIV, FTP, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, + LOCAL5, LOCAL6, LOCAL7. Case is unimportant. + + @since 0.8.1 */ + public + void setFacility(String facilityName) { + if(facilityName == null) { + return; + } + + syslogFacility = getFacility(facilityName); + if (syslogFacility == -1) { + System.err.println("["+facilityName + + "] is an unknown syslog facility. Defaulting to [USER]."); + syslogFacility = LOG_USER; + } + + this.initSyslogFacilityStr(); + + // If there is already a sqw, make it use the new facility. + if(sqw != null) { + sqw.setSyslogFacility(this.syslogFacility); } } /** - * Returns the value of the Facility option. - * - * See {@link #setFacility} for the set of allowed values. + Returns the value of the Facility option. */ - public String getFacility() { - return facilityStr; + public + String getFacility() { + return getFacilityString(syslogFacility); } - private void writeTimestamp() throws IOException { - StringBuffer timestamp = new StringBuffer(); - sdf.format(new Date(), timestamp, new FieldPosition(0)); - //According to the RFC the day of the month must be right justified with - // no leading 0. - if (timestamp.charAt(4) == '0') { - timestamp.setCharAt(4, ' '); - } - qw.write(timestamp.toString()); + /** + If the FacilityPrinting option is set to true, the printed + message will include the facility name of the application. It is + false by default. + */ + public + void setFacilityPrinting(boolean on) { + facilityPrinting = on; } - private void writeInitialParts(LoggingEvent event) throws IOException { - int pri = syslogFacility + event.getLevel().getSyslogEquivalent(); - qw.write("<"); - qw.write(String.valueOf(pri)); - qw.write(">"); - writeTimestamp(); - qw.write(' '); - qw.write(localHostname); - qw.write(' '); + /** + Returns the value of the FacilityPrinting option. + */ + public + boolean getFacilityPrinting() { + return facilityPrinting; } - - protected void subAppend(LoggingEvent event) { - try { - writeInitialParts(event); - String msg = layout.format(event); - qw.write(msg); - qw.flush(); -/* - if (layout.ignoresThrowable()) { - String[] s = event.getThrowableStrRep(); - if (s != null) { - int len = s.length; - if(len > 0) { - sqw.write(s[0]); - for(int i = 1; i < len; i++) { - sqw.write(TAB+s[i].substring(1)); - } - } - } - } -*/ - } catch (IOException ioe) { - } + /** + * If true, the appender will generate the HEADER part (that is, timestamp and host name) + * of the syslog packet. Default value is false for compatibility with existing behavior, + * however should be true unless there is a specific justification. + * @since 1.2.15 + */ + public final boolean getHeader() { + return header; } - /** - * If the FacilityPrinting option is set to true, the printed - * message will include the facility name of the application. It is - * false by default. - * - * @deprecated No effect in log4j 1.3 + /** + * Returns whether the appender produces the HEADER part (that is, timestamp and host name) + * of the syslog packet. + * @since 1.2.15 + */ + public final void setHeader(final boolean val) { + header = val; + } + + /** + * Sets the Tag option. + * + *

    + * If non-{@code null}, the printed HEADER will include the specified tag followed by a colon. If {@code null}, then no tag is printed. + *

    + *

    + * The default value is {@code null}. + *

    + * + * @param tag + * the TAG to be printed out with the header + * @see #getTag() + * @since 1.2.18 */ - public - void setFacilityPrinting(boolean on) { - facilityPrinting = on; + public void setTag(final String tag) { + String newTag = tag; + if (newTag != null) { + if (newTag.length() > MAX_TAG_LEN) { + newTag = newTag.substring(0, MAX_TAG_LEN); + } + if (NOT_ALPHANUM.matcher(newTag).find()) { + throw new IllegalArgumentException("tag contains non-alphanumeric characters"); + } + } + + this.tag = newTag; } /** - * Returns the value of the FacilityPrinting option. - * - * @deprecated No effect in log4j 1.3 + * Gets the TAG to be printed with the HEADER portion of the log message. This will return {@code null} if no TAG is to be printed. + *

    + * The default value is {@code null}. + *

    + * + * @return the TAG, max length 32. + * @see #setTag(String) + * @since 1.2.18 */ - public - boolean getFacilityPrinting() { - return facilityPrinting; - } - + public String getTag() { + return this.tag; + } + /** - * Logs a footer/header as info. + * Get the host name used to identify this appender. + * @return local host name + * @since 1.2.15 */ - private void info(String msg) { - if (msg == null) - return; - LoggingEvent event = new LoggingEvent(); - event.setLevel(Level.INFO); - try { - writeInitialParts(event); - } catch (IOException e) { - } - qw.write(msg); - qw.flush(); - } - - protected void writeFooter() { - if (layout != null) { - info(layout.getFooter()); + private String getLocalHostname() { + if (localHostname == null) { + try { + InetAddress addr = InetAddress.getLocalHost(); + localHostname = addr.getHostName(); + } catch (UnknownHostException uhe) { + localHostname = "UNKNOWN_HOST"; + } } - } + return localHostname; + } - protected void writeHeader() { - if (layout != null) { - info(layout.getHeader()); + /** + * Gets HEADER portion of packet. + * @param timeStamp number of milliseconds after the standard base time. + * @return HEADER portion of packet, will be zero-length string if header is false. + * @since 1.2.15 + */ + private String getPacketHeader(final long timeStamp) { + if (header) { + StringBuffer buf = new StringBuffer(dateFormat.format(new Date(timeStamp))); + // RFC 3164 says leading space, not leading zero on days 1-9 + if (buf.charAt(4) == '0') { + buf.setCharAt(4, ' '); + } + buf.append(getLocalHostname()); + buf.append(' '); + if(this.tag != null) { + buf.append(this.tag); + buf.append(": "); + } + return buf.toString(); } - } - + return ""; + } + /** + * Set header or footer of layout. + * @param msg message body, may not be null. + */ + private void sendLayoutMessage(final String msg) { + if (sqw != null) { + String packet = msg; + String hdr = getPacketHeader(new Date().getTime()); + if(facilityPrinting || hdr.length() > 0) { + StringBuffer buf = new StringBuffer(hdr); + if(facilityPrinting) { + buf.append(facilityStr); + } + buf.append(msg); + packet = buf.toString(); + } + sqw.setLevel(6); + sqw.write(packet); + } + } } diff --git a/src/main/java/org/apache/log4j/net/TelnetAppender.java b/src/main/java/org/apache/log4j/net/TelnetAppender.java index 91313359c5..5b49a2c92d 100644 --- a/src/main/java/org/apache/log4j/net/TelnetAppender.java +++ b/src/main/java/org/apache/log4j/net/TelnetAppender.java @@ -18,15 +18,17 @@ package org.apache.log4j.net; import org.apache.log4j.AppenderSkeleton; -import org.apache.log4j.Layout; +import org.apache.log4j.helpers.LogLog; import org.apache.log4j.spi.LoggingEvent; -import java.io.*; - -import java.net.*; - -import java.util.*; - +import java.io.IOException; +import java.io.PrintWriter; +import java.io.InterruptedIOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Vector; /**

    The TelnetAppender is a log4j appender that specializes in @@ -55,18 +57,14 @@ @author Jay Funnell */ + public class TelnetAppender extends AppenderSkeleton { + + private static final String EOL = "\r\n"; private SocketHandler sh; private int port = 23; - /** - * Creates a TelnetAppender. - */ - public TelnetAppender() { - super(false); - } - - /** + /** This appender requires a layout to format the text to the attached client(s). */ public boolean requiresLayout() { @@ -79,53 +77,58 @@ public void activateOptions() { try { sh = new SocketHandler(port); sh.start(); - } catch (IOException e) { - getLogger().error("Could not active TelnetAppender options for TelnetAppender named "+getName(), e); - throw new IllegalStateException("Could not create a SocketHandler for TelnetAppender named "+getName()); + } + catch(InterruptedIOException e) { + Thread.currentThread().interrupt(); + e.printStackTrace(); + } catch(IOException e) { + e.printStackTrace(); + } catch(RuntimeException e) { + e.printStackTrace(); } super.activateOptions(); } - public int getPort() { + public + int getPort() { return port; } - public void setPort(int port) { + public + void setPort(int port) { this.port = port; } + /** shuts down the appender. */ public void close() { if (sh != null) { - sh.close(); - try { - sh.join(); - } catch (InterruptedException e) { - } + sh.close(); + try { + sh.join(); + } catch(InterruptedException ex) { + Thread.currentThread().interrupt(); + } } } /** Handles a log event. For this appender, that means writing the message to each connected client. */ protected void append(LoggingEvent event) { - if(sh == null || !sh.hasConnections()) { - return; - } - - sh.send(this.layout.format(event)); - - if (layout.ignoresThrowable()) { - String[] s = event.getThrowableStrRep(); - - if (s != null) { - int len = s.length; - - for (int i = 0; i < len; i++) { - sh.send(s[i]); - sh.send(Layout.LINE_SEP); + if(sh != null) { + sh.send(layout.format(event)); + if(layout.ignoresThrowable()) { + String[] s = event.getThrowableStrRep(); + if (s != null) { + StringBuffer buf = new StringBuffer(); + for(int i = 0; i < s.length; i++) { + buf.append(s[i]); + buf.append(EOL); + } + sh.send(buf.toString()); + } } } - } } //---------------------------------------------------------- SocketHandler: @@ -134,107 +137,101 @@ protected void append(LoggingEvent event) { clients. It is threaded so that clients can connect/disconnect asynchronously. */ protected class SocketHandler extends Thread { + private Vector writers = new Vector(); private Vector connections = new Vector(); private ServerSocket serverSocket; private int MAX_CONNECTIONS = 20; - - private String encoding = "UTF-8"; - - public SocketHandler(int port) throws IOException { - serverSocket = new ServerSocket(port); - setName("TelnetAppender-" + getName() + "-" + port); - } public void finalize() { - close(); + close(); } - - /** make sure we close all network connections when this handler is destroyed. */ + + /** + * make sure we close all network connections when this handler is destroyed. + * @since 1.2.15 + */ public void close() { - for (Enumeration e = connections.elements(); e.hasMoreElements();) { - try { - ((Socket) e.nextElement()).close(); - } catch (IOException ex) { + synchronized(this) { + for(Enumeration e = connections.elements();e.hasMoreElements();) { + try { + ((Socket)e.nextElement()).close(); + } catch(InterruptedIOException ex) { + Thread.currentThread().interrupt(); + } catch(IOException ex) { + } catch(RuntimeException ex) { + } } } - - interrupt(); + try { serverSocket.close(); - } catch (IOException e) { - e.printStackTrace(); - } + } catch(InterruptedIOException ex) { + Thread.currentThread().interrupt(); + } catch(IOException ex) { + } catch(RuntimeException ex) { + } } /** sends a message to each of the clients in telnet-friendly output. */ - public void send(String message) { - boolean hasWriterError = false; - for (Enumeration e = writers.elements(); e.hasMoreElements();) { - PrintWriter writer = (PrintWriter) e.nextElement(); + public synchronized void send(final String message) { + Iterator ce = connections.iterator(); + for(Iterator e = writers.iterator();e.hasNext();) { + ce.next(); + PrintWriter writer = (PrintWriter)e.next(); writer.print(message); - hasWriterError |= writer.checkError(); - - } - // - // if any writer had an error then - // check all writers and remove any bad ones - if(hasWriterError) { - for (int i = writers.size() - 1; i >= 0; i--) { - if (((PrintWriter) writers.elementAt(i)).checkError()) { - writers.remove(i); - connections.remove(i); - } - } + if(writer.checkError()) { + ce.remove(); + e.remove(); + } } } - /** - Continually accepts client connections. Client connections - are refused when MAX_CONNECTIONS is reached. + /** + Continually accepts client connections. Client connections + are refused when MAX_CONNECTIONS is reached. */ public void run() { - while (!Thread.interrupted()) { + while(!serverSocket.isClosed()) { try { Socket newClient = serverSocket.accept(); - - // Bugzilla 26117: use an encoding to support EBCDIC machines - // Could make encoding a JavaBean property or even make TelnetAppender - // extend WriterAppender, which already has encoding support. - PrintWriter pw = new PrintWriter(new OutputStreamWriter(newClient.getOutputStream(), encoding)); - - if (connections.size() < MAX_CONNECTIONS) { - connections.addElement(newClient); - writers.addElement(pw); - pw.print( - "TelnetAppender v1.0 (" + connections.size() - + " active connections)\r\n\r\n"); - pw.flush(); + PrintWriter pw = new PrintWriter(newClient.getOutputStream()); + if(connections.size() < MAX_CONNECTIONS) { + synchronized(this) { + connections.addElement(newClient); + writers.addElement(pw); + pw.print("TelnetAppender v1.0 (" + connections.size() + + " active connections)" + EOL + EOL); + pw.flush(); + } } else { - pw.print("Too many connections.\r\n"); + pw.print("Too many connections." + EOL); pw.flush(); newClient.close(); } - } catch (Exception e) { - if (!Thread.interrupted()) - getLogger().error("Encountered error while in SocketHandler loop.", e); + } catch(Exception e) { + if (e instanceof InterruptedIOException || e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } + if (!serverSocket.isClosed()) { + LogLog.error("Encountered error while in SocketHandler loop.", e); + } break; } } try { - serverSocket.close(); - } catch (IOException ex) { + serverSocket.close(); + } catch(InterruptedIOException ex) { + Thread.currentThread().interrupt(); + } catch(IOException ex) { } - } - - /** - * Determines if socket hander has any active connections. - * @return true if any active connections. - */ - public boolean hasConnections() { - return connections.size() > 0; + + public SocketHandler(int port) throws IOException { + serverSocket = new ServerSocket(port); + setName("TelnetAppender-" + getName() + "-" + port); } + } } diff --git a/src/main/java/org/apache/log4j/net/UDPAppender.java b/src/main/java/org/apache/log4j/net/UDPAppender.java deleted file mode 100644 index 5bc39689e9..0000000000 --- a/src/main/java/org/apache/log4j/net/UDPAppender.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.net; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.UnknownHostException; - -import org.apache.log4j.AppenderSkeleton; -import org.apache.log4j.helpers.*; -import org.apache.log4j.spi.LoggingEvent; - - -/** - * Sends log information as a UDP datagrams. - * - *

    The UDPAppender is meant to be used as a diagnostic logging tool - * so that logging can be monitored by a simple UDP client. - * - *

    Messages are not sent as LoggingEvent objects but as text after - * applying the designated Layout. - * - *

    The port and remoteHost properties can be set in configuration properties. - * By setting the remoteHost to a broadcast address any number of clients can - * listen for log messages. - * - *

    This was inspired and really extended/copied from {@link SocketAppender}. - * Please see the docs for the proper credit to the authors of that class. - * - * @author Kevin Brown - * @author Scott Deboy - */ -public class UDPAppender extends AppenderSkeleton implements PortBased{ - /** - * The default port number for the UDP packets, 9991. - */ - public static final int DEFAULT_PORT = 9991; - - /** - We remember host name as String in addition to the resolved - InetAddress so that it can be returned via getOption(). - */ - String hostname; - String remoteHost; - String application; - String encoding; - String overrideProperties = "true"; - InetAddress address; - int port = DEFAULT_PORT; - DatagramSocket outSocket; - - // if there is something irrecoverably wrong with the settings, there is no - // point in sending out packeets. - boolean inError = false; - - public UDPAppender() { - super(false); - } - - /** - Sends UDP packets to the address and port. - */ - public UDPAppender(final InetAddress address, final int port) { - super(false); - this.address = address; - this.remoteHost = address.getHostName(); - this.port = port; - activateOptions(); - } - - /** - Sends UDP packets to the address and port. - */ - public UDPAppender(final String host, final int port) { - super(false); - this.port = port; - this.address = getAddressByName(host); - this.remoteHost = host; - activateOptions(); - } - - /** - Open the UDP sender for the RemoteHost and Port. - */ - public void activateOptions() { - try { - hostname = InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException uhe) { - try { - hostname = InetAddress.getLocalHost().getHostAddress(); - } catch (UnknownHostException uhe2) { - hostname = "unknown"; - } - } - - //allow system property of application to be primary - if (application == null) { - application = System.getProperty(Constants.APPLICATION_KEY); - } else { - if (System.getProperty(Constants.APPLICATION_KEY) != null) { - application = application + "-" + System.getProperty(Constants.APPLICATION_KEY); - } - } - - if(remoteHost != null) { - address = getAddressByName(remoteHost); - connect(address, port); - } else { - String err = "The RemoteHost property is required for SocketAppender named "+ name; - getLogger().error(err); - throw new IllegalStateException(err); - } - super.activateOptions(); - } - - /** - Close this appender. -

    This will mark the appender as closed and - call then {@link #cleanUp} method. - */ - public synchronized void close() { - if (closed) { - return; - } - - this.closed = true; - cleanUp(); - } - - /** - Close the UDP Socket and release the underlying - connector thread if it has been created - */ - public void cleanUp() { - if (outSocket != null) { - try { - outSocket.close(); - } catch (Exception e) { - getLogger().error("Could not close outSocket.", e); - } - - outSocket = null; - } - } - - void connect(InetAddress address, int port) { - if (this.address == null) { - return; - } - - try { - // First, close the previous connection if any. - cleanUp(); - outSocket = new DatagramSocket(); - outSocket.connect(address, port); - } catch (IOException e) { - getLogger().error( - "Could not open UDP Socket for sending.", e); - inError = true; - } - } - - public void append(LoggingEvent event) { - if(inError) { - return; - } - - if (event == null) { - return; - } - - if (address == null) { - return; - } - - if (outSocket != null) { - //if the values already exist, don't set (useful when forwarding from a simplesocketserver - if ( - (overrideProperties != null) - && overrideProperties.equalsIgnoreCase("true")) { - event.setProperty(Constants.HOSTNAME_KEY, hostname); - - if (application != null) { - event.setProperty(Constants.APPLICATION_KEY, application); - } - } - - try { - // TODO UDPAppender throws NullPointerException if the layout is not set - StringBuffer buf = new StringBuffer(layout.format(event)); - - byte[] payload; - if(encoding == null) { - payload = buf.toString().getBytes(); - } else { - payload = buf.toString().getBytes(encoding); - } - - DatagramPacket dp = - new DatagramPacket(payload, payload.length, address, port); - outSocket.send(dp); - //remove these properties, in case other appenders need to set them to different values - event.setProperty(Constants.HOSTNAME_KEY, null); - event.setProperty(Constants.APPLICATION_KEY, null); - } catch (IOException e) { - outSocket = null; - getLogger().warn("Detected problem with UDP connection: " + e); - } - } - } - - public boolean isActive() { - return !inError; - } - - InetAddress getAddressByName(String host) { - try { - return InetAddress.getByName(host); - } catch (Exception e) { - getLogger().error("Could not find address of [" + host + "].", e); - return null; - } - } - - /** - The UDPAppender uses layouts. Hence, this method returns - true. - */ - public boolean requiresLayout() { - return true; - } - - /** - The RemoteHost option takes a string value which should be - the host name or ipaddress to send the UDP packets. - */ - public void setRemoteHost(String host) { - remoteHost = host; - } - - /** - Returns value of the RemoteHost option. - */ - public String getRemoteHost() { - return remoteHost; - } - - /** - The App option takes a string value which should be the name of the application getting logged. - If property was already set (via system property), don't set here. - */ - public void setApplication(String app) { - this.application = app; - } - - /** - Returns value of the App option. - */ - public String getApplication() { - return application; - } - - /** - The Encoding option specifies how the bytes are encoded. If this option is not specified, - the System encoding is used. - */ - public void setEncoding(String encoding) { - this.encoding = encoding; - } - - /** - Returns value of the Encoding option. - */ - public String getEncoding() { - return encoding; - } - - /** - The OverrideProperties option allows configurations where the appender does not apply - the machinename/appname properties - the properties will be used as provided. - */ - public void setOverrideProperties(String overrideProperties) { - this.overrideProperties = overrideProperties; - } - - /** - Returns value of the OverrideProperties option. - */ - public String getOverrideProperties() { - return overrideProperties; - } - - /** - The Port option takes a positive integer representing - the port where UDP packets will be sent. - */ - public void setPort(int port) { - this.port = port; - } - - /** - Returns value of the Port option. - */ - public int getPort() { - return port; - } - -} diff --git a/src/main/java/org/apache/log4j/net/UDPReceiver.java b/src/main/java/org/apache/log4j/net/UDPReceiver.java deleted file mode 100644 index 3783fc72fb..0000000000 --- a/src/main/java/org/apache/log4j/net/UDPReceiver.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.net; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.SocketException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.log4j.plugins.Pauseable; -import org.apache.log4j.plugins.Receiver; -import org.apache.log4j.spi.Decoder; -import org.apache.log4j.spi.LoggingEvent; - - -/** - * Receive LoggingEvents encoded with an XMLLayout, convert the XML data to a - * LoggingEvent and post the LoggingEvent. - * - * @author Scott Deboy - * - */ -public class UDPReceiver extends Receiver implements PortBased, Pauseable { - private static final int PACKET_LENGTH = 16384; - private UDPReceiverThread receiverThread; - private String encoding; - - //default to log4j xml decoder - private String decoder = "org.apache.log4j.xml.XMLDecoder"; - private Decoder decoderImpl; - protected boolean paused; - private transient boolean closed = false; - private int port; - private DatagramSocket socket; - UDPHandlerThread handlerThread; - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - /** - * The Encoding option specifies how the bytes are encoded. If this - * option is not specified, the system encoding will be used. - * */ - public void setEncoding(String encoding) { - this.encoding = encoding; - } - - /** - * Returns value of the Encoding option. - */ - public String getEncoding() { - return encoding; - } - - public String getDecoder() { - return decoder; - } - - public void setDecoder(String decoder) { - this.decoder = decoder; - } - - public boolean isPaused() { - return paused; - } - - public void setPaused(boolean b) { - paused = b; - } - - public synchronized void shutdown() { - if(closed == true) { - return; - } - closed = true; - // Closing the datagram socket will unblock the UDPReceiverThread if it is - // was waiting to receive data from the socket. - socket.close(); - - try { - if(handlerThread != null) { - handlerThread.close(); - handlerThread.join(); - } - if(receiverThread != null) { - receiverThread.join(); - } - } catch(InterruptedException ie) { - } - } - - /** - Returns true if this receiver is active. */ -// public synchronized boolean isActive() { -// return isActive; -//} - - public void activateOptions() { - try { - Class c = Class.forName(decoder); - Object o = c.newInstance(); - - if (o instanceof Decoder) { - this.decoderImpl = (Decoder) o; - } - } catch (ClassNotFoundException cnfe) { - getLogger().warn("Unable to find decoder", cnfe); - } catch (IllegalAccessException iae) { - getLogger().warn("Could not construct decoder", iae); - } catch (InstantiationException ie) { - getLogger().warn("Could not construct decoder", ie); - } - - try { - socket = new DatagramSocket(port); - receiverThread = new UDPReceiverThread(); - receiverThread.start(); - handlerThread = new UDPHandlerThread(); - handlerThread.start(); - } catch (IOException ioe) { - ioe.printStackTrace(); - } - } - - class UDPHandlerThread extends Thread { - private List list = new ArrayList(); - - public UDPHandlerThread() { - setDaemon(true); - } - - public void append(String data) { - synchronized (list) { - list.add(data); - list.notify(); - } - } - - /** - * Allow the UDPHandlerThread to wakeup and exit gracefully. - */ - void close() { - synchronized(list) { - list.notify(); - } - } - - public void run() { - ArrayList list2 = new ArrayList(); - - while (!UDPReceiver.this.closed) { - synchronized (list) { - try { - while (!UDPReceiver.this.closed && list.size() == 0) { - list.wait(); - } - - if (list.size() > 0) { - list2.addAll(list); - list.clear(); - } - } catch (InterruptedException ie) { - } - } - - if (list2.size() > 0) { - Iterator iter = list2.iterator(); - - while (iter.hasNext()) { - String data = (String) iter.next(); - List v = decoderImpl.decodeEvents(data); - - if (v != null) { - Iterator eventIter = v.iterator(); - - while (eventIter.hasNext()) { - if (!isPaused()) { - doPost((LoggingEvent) eventIter.next()); - } - } - } - } - - list2.clear(); - } else { - try { - synchronized (this) { - wait(1000); - } - } catch (InterruptedException ie) { - } - } - } // while - getLogger().debug(UDPReceiver.this.getName()+ "'s handler thread is exiting"); - } // run - } // UDPHandlerThread - - class UDPReceiverThread extends Thread { - public UDPReceiverThread() { - setDaemon(true); - } - - public void run() { - byte[] b = new byte[PACKET_LENGTH]; - DatagramPacket p = new DatagramPacket(b, b.length); - - while (!UDPReceiver.this.closed) { - try { - socket.receive(p); - - //this string constructor which accepts a charset throws an exception if it is - //null - if (encoding == null) { - handlerThread.append( - new String(p.getData(), 0, p.getLength())); - } else { - handlerThread.append( - new String(p.getData(), 0, p.getLength(), encoding)); - } - } catch (SocketException se) { - //disconnected - } catch (IOException ioe) { - ioe.printStackTrace(); - } - } - - //LogLog.debug(UDPReceiver.this.getName() + "'s thread is ending."); - } - } -} diff --git a/src/main/java/org/apache/log4j/net/XMLSocketNode.java b/src/main/java/org/apache/log4j/net/XMLSocketNode.java deleted file mode 100644 index 86718b18c3..0000000000 --- a/src/main/java/org/apache/log4j/net/XMLSocketNode.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.net; - -import org.apache.log4j.*; -import org.apache.log4j.helpers.Constants; -import org.apache.log4j.plugins.Receiver; -import org.apache.log4j.spi.*; - -import java.io.IOException; -import java.io.InputStream; - -import java.net.Socket; - -import java.util.Iterator; -import java.util.List; - - -/** - Read {@link LoggingEvent} objects sent from a remote client using XML over - Sockets (TCP). These logging events are logged according to local - policy, as if they were generated locally. - -

    For example, the socket node might decide to log events to a - local file and also resent them to a second socket node. - - @author Scott Deboy ; - - @since 0.8.4 -*/ -public class XMLSocketNode extends ComponentBase implements Runnable { - Socket socket; - Receiver receiver; - Decoder decoder; - SocketNodeEventListener listener; - - /** - Constructor for socket and logger repository. */ - public XMLSocketNode( - String decoder, Socket socket, LoggerRepository hierarchy) { - this.repository = hierarchy; - try { - Class c = Class.forName(decoder); - Object o = c.newInstance(); - - if (o instanceof Decoder) { - this.decoder = (Decoder) o; - } - } catch (ClassNotFoundException cnfe) { - getLogger().warn("Unable to find decoder", cnfe); - } catch (IllegalAccessException iae) { - getLogger().warn("Unable to construct decoder", iae); - } catch (InstantiationException ie) { - getLogger().warn("Unable to construct decoder", ie); - } - - this.socket = socket; - } - - /** - Constructor for socket and reciever. */ - public XMLSocketNode(String decoder, Socket socket, Receiver receiver) { - try { - Class c = Class.forName(decoder); - Object o = c.newInstance(); - - if (o instanceof Decoder) { - this.decoder = (Decoder) o; - } - } catch (ClassNotFoundException cnfe) { - getLogger().warn("Unable to find decoder", cnfe); - } catch (IllegalAccessException iae) { - getLogger().warn("Unable to construct decoder", iae); - } catch (InstantiationException ie) { - getLogger().warn("Unable to construct decoder", ie); - } - - this.socket = socket; - this.receiver = receiver; - } - - /** - Set the event listener on this node. */ - public void setListener(SocketNodeEventListener _listener) { - listener = _listener; - } - - public void run() { - Logger remoteLogger; - Exception listenerException = null; - InputStream is = null; - - if ((this.receiver == null) || (this.decoder == null)) { - is = null; - listenerException = - new Exception( - "No receiver or decoder provided. Cannot process xml socket events"); - getLogger().error( - "Exception constructing XML Socket Receiver", listenerException); - } - - try { - is = socket.getInputStream(); - } catch (Exception e) { - is = null; - listenerException = e; - getLogger().error("Exception opening ObjectInputStream to " + socket, e); - } - - if (is != null) { - String remoteInfo = - socket.getInetAddress().getHostName() + ":" + socket.getPort(); - - try { - //read data from the socket - //it's up to the individual decoder to handle incomplete event data - while (true) { - byte[] b = new byte[1024]; - int length = is.read(b); - if (length == -1) { - getLogger().info( - "no bytes read from stream - closing connection."); - break; - } - List v = decoder.decodeEvents(new String(b, 0, length)); - - if (v != null) { - Iterator iter = v.iterator(); - - while (iter.hasNext()) { - LoggingEvent e = (LoggingEvent) iter.next(); - - //if machinename property was not set (the case if properties - //not supported by the DTD), use remoteinfo as machine name - if (e.getProperty(Constants.HOSTNAME_KEY) == null) { - e.setProperty(Constants.HOSTNAME_KEY, remoteInfo); - } - - // store the known remote info in an event property - e.setProperty("log4j.remoteSourceInfo", remoteInfo); - - // if configured with a receiver, tell it to post the event - if (receiver != null) { - receiver.doPost(e); - - // else post it via the hierarchy - } else { - // get a logger from the hierarchy. The name of the logger - // is taken to be the name contained in the event. - remoteLogger = repository.getLogger(e.getLoggerName()); - - //event.logger = remoteLogger; - // apply the logger-level filter - if ( - e.getLevel().isGreaterOrEqual( - remoteLogger.getEffectiveLevel())) { - // finally log the event as if was generated locally - remoteLogger.callAppenders(e); - } - } - } - } - } - } catch (java.io.EOFException e) { - getLogger().info("Caught java.io.EOFException closing connection."); - listenerException = e; - } catch (java.net.SocketException e) { - getLogger().info( - "Caught java.net.SocketException closing connection."); - listenerException = e; - } catch (IOException e) { - getLogger().info("Caught java.io.IOException: " + e); - getLogger().info("Closing connection."); - listenerException = e; - } catch (Exception e) { - getLogger().error("Unexpected exception. Closing connection.", e); - listenerException = e; - } - } - - // close the socket - try { - if (is != null) { - is.close(); - } - } catch (Exception e) { - //logger.info("Could not close connection.", e); - } - - // send event to listener, if configured - if (listener != null) { - listener.socketClosedEvent(listenerException); - } - } -} diff --git a/src/main/java/org/apache/log4j/net/XMLSocketReceiver.java b/src/main/java/org/apache/log4j/net/XMLSocketReceiver.java deleted file mode 100644 index 17a0041015..0000000000 --- a/src/main/java/org/apache/log4j/net/XMLSocketReceiver.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.net; - -import java.net.ServerSocket; -import java.net.Socket; -import java.util.List; -import java.util.Vector; - -import org.apache.log4j.plugins.Pauseable; -import org.apache.log4j.plugins.Plugin; -import org.apache.log4j.plugins.Receiver; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggingEvent; - - -/** - XMLSocketReceiver receives a remote logging event via XML on a configured - socket and "posts" it to a LoggerRepository as if the event were - generated locally. This class is designed to receive events from - the XMLSocketAppender class (or classes that send compatible events). - -

    Once the event has been "posted", it will be handled by the - appenders currently configured in the LoggerRespository. - - @author Mark Womack - @author Scott Deboy - - @since 1.3 -*/ -public class XMLSocketReceiver extends Receiver implements Runnable, PortBased, Pauseable { - protected boolean active = false; - private boolean paused; - //default to log4j xml decoder - protected String decoder = "org.apache.log4j.xml.XMLDecoder"; - private ServerSocket serverSocket; - private List socketList = new Vector(); - private Thread rThread; - public static final int DEFAULT_PORT = 4448; - protected int port = DEFAULT_PORT; - - public XMLSocketReceiver() { - } - - public XMLSocketReceiver(int _port) { - port = _port; - } - - public XMLSocketReceiver(int _port, LoggerRepository _repository) { - port = _port; - repository = _repository; - } - - /** - Get the port to receive logging events on. */ - public int getPort() { - return port; - } - - /** - Set the port to receive logging events on. */ - public void setPort(int _port) { - port = _port; - } - - public String getDecoder() { - return decoder; - } - - public void setDecoder(String _decoder) { - decoder = _decoder; - } - - public boolean isPaused() { - return paused; - } - - public void setPaused(boolean b) { - paused = b; - } - - /** - * Returns true if the receiver is the same class and they are - * configured for the same properties, and super class also considers - * them to be equivalent. This is used by PluginRegistry when determining - * if the a similarly configured receiver is being started. - * - * @param testPlugin The plugin to test equivalency against. - * @return boolean True if the testPlugin is equivalent to this plugin. - */ - public boolean isEquivalent(Plugin testPlugin) { - if ((testPlugin != null) && testPlugin instanceof XMLSocketReceiver) { - XMLSocketReceiver sReceiver = (XMLSocketReceiver) testPlugin; - - return (port == sReceiver.getPort() && super.isEquivalent(testPlugin)); - } - - return false; - } - - public int hashCode() { - - int result = 37 * (repository != null? repository.hashCode():0); - result = result * 37 + port; - return (result * 37 + (getName() != null? getName().hashCode():0)); - } - - /** - Returns true if this receiver is active. */ - public synchronized boolean isActive() { - return active; - } - - /** - Starts the SocketReceiver with the current options. */ - public void activateOptions() { - if (!isActive()) { - rThread = new Thread(this); - rThread.setDaemon(true); - rThread.start(); - active = true; - } - } - - /** - Called when the receiver should be stopped. Closes the - server socket and all of the open sockets. */ - public synchronized void shutdown() { - // mark this as no longer running - active = false; - - if (rThread != null) { - rThread.interrupt(); - rThread = null; - } - doShutdown(); - } - - /** - * Does the actual shutting down by closing the server socket - * and any connected sockets that have been created. - */ - private synchronized void doShutdown() { - active = false; - - getLogger().debug("{} doShutdown called", getName()); - - // close the server socket - closeServerSocket(); - - // close all of the accepted sockets - closeAllAcceptedSockets(); - } - - /** - * Closes the server socket, if created. - */ - private void closeServerSocket() { - getLogger().debug("{} closing server socket", getName()); - - try { - if (serverSocket != null) { - serverSocket.close(); - } - } catch (Exception e) { - // ignore for now - } - - serverSocket = null; - } - - /** - * Closes all the connected sockets in the List. - */ - private synchronized void closeAllAcceptedSockets() { - for (int x = 0; x < socketList.size(); x++) { - try { - ((Socket) socketList.get(x)).close(); - } catch (Exception e) { - // ignore for now - } - } - - // clear member variables - socketList.clear(); - } - - /** - Loop, accepting new socket connections. */ - public void run() { - /** - * Ensure we start fresh. - */ - getLogger().debug("performing socket cleanup prior to entering loop for {}", name); - closeServerSocket(); - closeAllAcceptedSockets(); - getLogger().debug("socket cleanup complete for {}", name); - active = true; - - // start the server socket - try { - serverSocket = new ServerSocket(port); - } catch (Exception e) { - getLogger().error( - "error starting SocketReceiver (" + this.getName() - + "), receiver did not start", e); - active = false; - doShutdown(); - - return; - } - - Socket socket = null; - - try { - getLogger().debug("in run-about to enter while isactiveloop"); - - active = true; - - while (!rThread.isInterrupted()) { - // if we have a socket, start watching it - if (socket != null) { - getLogger().debug("socket not null - creating and starting socketnode"); - socketList.add(socket); - - XMLSocketNode node = new XMLSocketNode(decoder, socket, this); - node.setLoggerRepository(this.repository); - new Thread(node).start(); - socket = null; - } - - getLogger().debug("waiting to accept socket"); - - // wait for a socket to open, then loop to start it - socket = serverSocket.accept(); - getLogger().debug("accepted socket"); - } - - // socket not watched because we a no longer running - // so close it now. - if (socket != null) { - socket.close(); - } - } catch (Exception e) { - getLogger().warn( - "socket server disconnected, stopping"); - } - } - - /* (non-Javadoc) - * @see org.apache.log4j.plugins.Receiver#doPost(org.apache.log4j.spi.LoggingEvent) - */ - public void doPost(LoggingEvent event) { - if(!isPaused()){ - super.doPost(event); - } - } - - -} diff --git a/src/main/java/org/apache/log4j/net/ZeroConfSupport.java b/src/main/java/org/apache/log4j/net/ZeroConfSupport.java new file mode 100644 index 0000000000..32ac971cbd --- /dev/null +++ b/src/main/java/org/apache/log4j/net/ZeroConfSupport.java @@ -0,0 +1,206 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.net; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +import org.apache.log4j.helpers.LogLog; + +public class ZeroConfSupport { + private static Object jmDNS = initializeJMDNS(); + + Object serviceInfo; + private static Class jmDNSClass; + private static Class serviceInfoClass; + + public ZeroConfSupport(String zone, int port, String name, Map properties) { + //if version 3 is available, use it to constuct a serviceInfo instance, otherwise support the version1 API + boolean isVersion3 = false; + try { + //create method is in version 3, not version 1 + jmDNSClass.getMethod("create", null); + isVersion3 = true; + } catch (NoSuchMethodException e) { + //no-op + } + + if (isVersion3) { + LogLog.debug("using JmDNS version 3 to construct serviceInfo instance"); + serviceInfo = buildServiceInfoVersion3(zone, port, name, properties); + } else { + LogLog.debug("using JmDNS version 1.0 to construct serviceInfo instance"); + serviceInfo = buildServiceInfoVersion1(zone, port, name, properties); + } + } + + public ZeroConfSupport(String zone, int port, String name) { + this(zone, port, name, new HashMap()); + } + + private static Object createJmDNSVersion1() + { + try { + return jmDNSClass.newInstance(); + } catch (InstantiationException e) { + LogLog.warn("Unable to instantiate JMDNS", e); + } catch (IllegalAccessException e) { + LogLog.warn("Unable to instantiate JMDNS", e); + } + return null; + } + + private static Object createJmDNSVersion3() + { + try { + Method jmDNSCreateMethod = jmDNSClass.getMethod("create", null); + return jmDNSCreateMethod.invoke(null, null); + } catch (IllegalAccessException e) { + LogLog.warn("Unable to instantiate jmdns class", e); + } catch (NoSuchMethodException e) { + LogLog.warn("Unable to access constructor", e); + } catch (InvocationTargetException e) { + LogLog.warn("Unable to call constructor", e); + } + return null; + } + + private Object buildServiceInfoVersion1(String zone, int port, String name, Map properties) { + //version 1 uses a hashtable + Hashtable hashtableProperties = new Hashtable(properties); + try { + Class[] args = new Class[6]; + args[0] = String.class; + args[1] = String.class; + args[2] = int.class; + args[3] = int.class; //weight (0) + args[4] = int.class; //priority (0) + args[5] = Hashtable.class; + Constructor constructor = serviceInfoClass.getConstructor(args); + Object[] values = new Object[6]; + values[0] = zone; + values[1] = name; + values[2] = new Integer(port); + values[3] = new Integer(0); + values[4] = new Integer(0); + values[5] = hashtableProperties; + Object result = constructor.newInstance(values); + LogLog.debug("created serviceinfo: " + result); + return result; + } catch (IllegalAccessException e) { + LogLog.warn("Unable to construct ServiceInfo instance", e); + } catch (NoSuchMethodException e) { + LogLog.warn("Unable to get ServiceInfo constructor", e); + } catch (InstantiationException e) { + LogLog.warn("Unable to construct ServiceInfo instance", e); + } catch (InvocationTargetException e) { + LogLog.warn("Unable to construct ServiceInfo instance", e); + } + return null; + } + + private Object buildServiceInfoVersion3(String zone, int port, String name, Map properties) { + try { + Class[] args = new Class[6]; + args[0] = String.class; //zone/type + args[1] = String.class; //display name + args[2] = int.class; //port + args[3] = int.class; //weight (0) + args[4] = int.class; //priority (0) + args[5] = Map.class; + Method serviceInfoCreateMethod = serviceInfoClass.getMethod("create", args); + Object[] values = new Object[6]; + values[0] = zone; + values[1] = name; + values[2] = new Integer(port); + values[3] = new Integer(0); + values[4] = new Integer(0); + values[5] = properties; + Object result = serviceInfoCreateMethod.invoke(null, values); + LogLog.debug("created serviceinfo: " + result); + return result; + } catch (IllegalAccessException e) { + LogLog.warn("Unable to invoke create method", e); + } catch (NoSuchMethodException e) { + LogLog.warn("Unable to find create method", e); + } catch (InvocationTargetException e) { + LogLog.warn("Unable to invoke create method", e); + } + return null; + } + + public void advertise() { + try { + Method method = jmDNSClass.getMethod("registerService", new Class[]{serviceInfoClass}); + method.invoke(jmDNS, new Object[]{serviceInfo}); + LogLog.debug("registered serviceInfo: " + serviceInfo); + } catch(IllegalAccessException e) { + LogLog.warn("Unable to invoke registerService method", e); + } catch(NoSuchMethodException e) { + LogLog.warn("No registerService method", e); + } catch(InvocationTargetException e) { + LogLog.warn("Unable to invoke registerService method", e); + } + } + + public void unadvertise() { + try { + Method method = jmDNSClass.getMethod("unregisterService", new Class[]{serviceInfoClass}); + method.invoke(jmDNS, new Object[]{serviceInfo}); + LogLog.debug("unregistered serviceInfo: " + serviceInfo); + } catch(IllegalAccessException e) { + LogLog.warn("Unable to invoke unregisterService method", e); + } catch(NoSuchMethodException e) { + LogLog.warn("No unregisterService method", e); + } catch(InvocationTargetException e) { + LogLog.warn("Unable to invoke unregisterService method", e); + } + } + + private static Object initializeJMDNS() { + try { + jmDNSClass = Class.forName("javax.jmdns.JmDNS"); + serviceInfoClass = Class.forName("javax.jmdns.ServiceInfo"); + } catch (ClassNotFoundException e) { + LogLog.warn("JmDNS or serviceInfo class not found", e); + } + + //if version 3 is available, use it to constuct a serviceInfo instance, otherwise support the version1 API + boolean isVersion3 = false; + try { + //create method is in version 3, not version 1 + jmDNSClass.getMethod("create", null); + isVersion3 = true; + } catch (NoSuchMethodException e) { + //no-op + } + + if (isVersion3) { + return createJmDNSVersion3(); + } else { + return createJmDNSVersion1(); + } + } + + public static Object getJMDNSInstance() { + return jmDNS; + } +} diff --git a/src/main/java/org/apache/log4j/net/package.html b/src/main/java/org/apache/log4j/net/package.html index aef73e3e2e..1d2e96556c 100644 --- a/src/main/java/org/apache/log4j/net/package.html +++ b/src/main/java/org/apache/log4j/net/package.html @@ -1,4 +1,21 @@ + diff --git a/src/main/java/org/apache/log4j/net/test/Loop.java b/src/main/java/org/apache/log4j/net/test/Loop.java deleted file mode 100644 index ee12dab9f9..0000000000 --- a/src/main/java/org/apache/log4j/net/test/Loop.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.net.test; - -import org.apache.log4j.*; -import org.apache.log4j.net.SocketAppender; - -public class Loop { - - public static void main(String[] args) { - - - Logger root = Logger.getRootLogger(); - final Logger logger = Logger.getLogger(Loop.class); - - if(args.length != 2) - usage("Wrong number of arguments."); - - String host = args[0]; - int port = 0; - - try { - port = Integer.valueOf(args[1]).intValue(); - } - catch (NumberFormatException e) { - usage("Argument [" + args[1] + "] is not in proper int form."); - } - - SocketAppender sa = new SocketAppender(host, port); - Layout layout = new PatternLayout("%5p [%t] %x %c - %m\n"); - Appender so = new ConsoleAppender(layout, "System.out"); - root.addAppender(sa); - root.addAppender(so); - - int i = 0; - - while(true) { - NDC.push(""+ (i++)); - logger.debug("Debug message."); - root.info("Info message."); - NDC.pop(); - } - - } - - static - void usage(String msg) { - System.err.println(msg); - System.err.println( - "Usage: java " +Loop.class.getName() + " host port"); - System.exit(1); - } - - -} diff --git a/src/main/java/org/apache/log4j/net/test/SMTPMin.java b/src/main/java/org/apache/log4j/net/test/SMTPMin.java deleted file mode 100644 index 1ce03e455a..0000000000 --- a/src/main/java/org/apache/log4j/net/test/SMTPMin.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.net.test; - -import org.apache.log4j.*; - -public class SMTPMin { - - final static Logger logger = Logger.getLogger(SMTPMin.class); - - public - static - void main(String argv[]) { - if(argv.length == 1) - init(argv[0]); - else - usage("Wrong number of arguments."); - - NDC.push("some context"); - test(); - } - - static - void usage(String msg) { - System.err.println(msg); - System.err.println("Usage: java " + SMTPMin.class.getName() - + " configFile"); - System.exit(1); - } - - static - void init(String configFile) { - PropertyConfigurator.configure(configFile); - } - - - static - void test() { - int i = 0; - logger.debug( "Message " + i++); - logger.debug("Message " + i++, new Exception("Just testing.")); - logger.info( "Message " + i++); - logger.warn( "Message " + i++); - logger.error( "Message " + i++); - logger.log(Level.FATAL, "Message " + i++); - LogManager.shutdown(); - Thread.currentThread().getThreadGroup().list(); - } - -} diff --git a/src/main/java/org/apache/log4j/net/test/SocketMin.java b/src/main/java/org/apache/log4j/net/test/SocketMin.java deleted file mode 100644 index 5203f7161a..0000000000 --- a/src/main/java/org/apache/log4j/net/test/SocketMin.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.net.test; - -import org.apache.log4j.Logger; -import org.apache.log4j.BasicConfigurator; -import org.apache.log4j.Level; -import org.apache.log4j.net.SocketAppender; -import org.apache.log4j.NDC; - -import java.io.IOException; -import java.io.InputStreamReader; - -public class SocketMin { - - static Logger logger = Logger.getLogger(SyslogMin.class); - static SocketAppender s; - - public - static - void main(String argv[]) { - if(argv.length == 3) - init(argv[0], argv[1]); - else - usage("Wrong number of arguments."); - - NDC.push("some context"); - if(argv[2].equals("true")) - loop(); - else - test(); - - s.close(); - } - - static - void usage(String msg) { - System.err.println(msg); - System.err.println("Usage: java " + SocketMin.class - + " host port true|false"); - System.exit(1); - } - - static - void init(String host, String portStr) { - Logger root = Logger.getRootLogger(); - BasicConfigurator.configure(); - try { - int port = Integer.parseInt(portStr); - logger.info("Creating socket appender ("+host+","+port+")."); - s = new SocketAppender(host, port); - s.setName("S"); - root.addAppender(s); - } - catch(java.lang.NumberFormatException e) { - e.printStackTrace(); - usage("Could not interpret port number ["+ portStr +"]."); - } - catch(Exception e) { - System.err.println("Could not start!"); - e.printStackTrace(); - System.exit(1); - } - } - - static - void loop() { - Logger root = Logger.getRootLogger(); - InputStreamReader in = new InputStreamReader(System.in); - try { - System.out.println("Type 'q' to quit"); - int i; - int k = 0; - while (true) { - logger.debug("Message " + k++); - logger.info("Message " + k++); - logger.warn("Message " + k++); - logger.error("Message " + k++, new Exception("Just testing")); - i = in.read(); - if (i == -1) break; - if (i == 'q') break; - if (i == 'r') { - System.out.println("Removing appender S"); - root.removeAppender("S"); - } - } - } catch (IOException e) { - } - } - - static - void test() { - int i = 0; - logger.debug( "Message " + i++); - logger.info( "Message " + i++); - logger.warn( "Message " + i++); - logger.error( "Message " + i++); - logger.log(Level.FATAL, "Message " + i++); - logger.debug("Message " + i++, new Exception("Just testing.")); - } -} diff --git a/src/main/java/org/apache/log4j/net/test/SyslogMin.java b/src/main/java/org/apache/log4j/net/test/SyslogMin.java deleted file mode 100644 index 0e1219127a..0000000000 --- a/src/main/java/org/apache/log4j/net/test/SyslogMin.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.log4j.net.test; - -import org.apache.log4j.Logger; -import org.apache.log4j.Level; -import org.apache.log4j.PropertyConfigurator; -import org.apache.log4j.NDC; - - -public class SyslogMin { - - final static Logger LOG = Logger.getLogger(SyslogMin.class.getName()); - - public - static - void main(String argv[]) { - - if(argv.length == 1) { - ProgramInit(argv[0]); - } - else { - Usage("Wrong number of arguments."); - } - test("someHost"); - } - - - static - void Usage(String msg) { - System.err.println(msg); - System.err.println( "Usage: java " + SyslogMin.class + " configFile"); - System.exit(1); - } - - - static - void ProgramInit(String configFile) { - int port = 0; - PropertyConfigurator.configure(configFile); - } - - static - void test(String host) { - NDC.push(host); - int i = 0; - LOG.debug( "Message " + i++); - LOG.info( "Message " + i++); - LOG.warn( "Message " + i++); - LOG.error( "Message " + i++); - LOG.log(Level.FATAL, "Message " + i++); - LOG.debug("Message " + i++, new Exception("Just testing.")); - } -} diff --git a/src/main/java/org/apache/log4j/net/test/intermediarySocketServer.lcf b/src/main/java/org/apache/log4j/net/test/intermediarySocketServer.lcf deleted file mode 100644 index af3a758de4..0000000000 --- a/src/main/java/org/apache/log4j/net/test/intermediarySocketServer.lcf +++ /dev/null @@ -1,23 +0,0 @@ - -# ---------------------------------------------------------------------------- -# This config file is intended to be used by an intermediary SocketServer that -# relays its log output to another SocketServer. This is used mostly to test -# SocketServer cascading. -# ---------------------------------------------------------------------------- - - -log4j.configDebug=true - -log4j.rootCategory=DEBUG, SOCKETSERV, CON - -log4j.category.org.apache.log4j.net=DEBUG -log4j.appender.SOCKETSERV=org.apache.log4j.net.SocketAppender -log4j.appender.SOCKETSERV.RemoteHost=localhost -log4j.appender.SOCKETSERV.Port=15000 -log4j.appender.SOCKETSERV.layout=org.apache.log4j.PatternLayout -log4j.appender.SOCKETSERV.layout.ConversionPattern=%-5r %-5p [%t] %c{2} %x - %m%n - - -log4j.appender.CON=org.apache.log4j.ConsoleAppender -log4j.appender.CON.layout=org.apache.log4j.PatternLayout -log4j.appender.CON.layout.ConversionPattern=%-5r %-5p [%t] %c{2} %x - %m%n \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/net/test/jms.lcf b/src/main/java/org/apache/log4j/net/test/jms.lcf deleted file mode 100644 index a8e353594e..0000000000 --- a/src/main/java/org/apache/log4j/net/test/jms.lcf +++ /dev/null @@ -1,6 +0,0 @@ - -log4j.rootCategory=DEBUG, A1 -log4j.configDebug=true -log4j.appender.A1=org.apache.log4j.net.JMSAppender -log4j.appender.A1.TopicBindingName=LOGBN -log4j.appender.A1.TopicConnectionFactoryBindingName=TCFBN diff --git a/src/main/java/org/apache/log4j/net/test/logging.lcf b/src/main/java/org/apache/log4j/net/test/logging.lcf deleted file mode 100644 index e10dbc8c2c..0000000000 --- a/src/main/java/org/apache/log4j/net/test/logging.lcf +++ /dev/null @@ -1,9 +0,0 @@ -log4j.rootCategory= , testAppender -log4j.configDebug=true -log4j.appender.testAppender=org.apache.log4j.net.SyslogAppender -log4j.appender.testAppender.SyslogHost=localhost -log4j.appender.testAppender.Facility=LOCAL0 -log4j.appender.testAppender.FacilityPrinting= -log4j.appender.testAppender.layout=org.apache.log4j.TTCCLayout -log4j.appender.testAppender.layout.DateFormat=NULL -log4j.appender.testAppender.layout.TimeZone= diff --git a/src/main/java/org/apache/log4j/net/test/loop.lcf b/src/main/java/org/apache/log4j/net/test/loop.lcf deleted file mode 100644 index 5913848788..0000000000 --- a/src/main/java/org/apache/log4j/net/test/loop.lcf +++ /dev/null @@ -1,9 +0,0 @@ -log4j.rootCategory= , A1 -log4j.configDebug=true -log4j.appender.A1=org.apache.log4j.RollingFileAppender -log4j.appender.A1.Append=true -log4j.appender.A1.File=loop.log -log4j.appender.A1.MaxFileSize=100KB -log4j.appender.A1.layout=org.apache.log4j.PatternLayout -log4j.appender.A1.layout.ConversionPattern=%p [%t] - %m\n - diff --git a/src/main/java/org/apache/log4j/net/test/socketClient.lcf b/src/main/java/org/apache/log4j/net/test/socketClient.lcf deleted file mode 100644 index 66cc5aaa78..0000000000 --- a/src/main/java/org/apache/log4j/net/test/socketClient.lcf +++ /dev/null @@ -1,20 +0,0 @@ -# ------------------------------------------------------------------------- -# This config file is intended to be used by a client wishing to log using -# a SocketAppender to a SyslogServer or equivalent. -# ------------------------------------------------------------------------- - -log4j.configDebug=true - -log4j.rootCategory=DEBUG, A1, CON - -log4j.category.org.apache.log4j.net=DEBUG -log4j.appender.A1=org.apache.log4j.net.SocketAppender -log4j.appender.A1.RemoteHost=localhost -log4j.appender.A1.Port=15000 -log4j.appender.A1.layout=org.apache.log4j.PatternLayout -log4j.appender.A1.layout.ConversionPattern=%-5r %-5p [%t] %c{2} %x - %m%n - - -log4j.appender.CON=org.apache.log4j.ConsoleAppender -log4j.appender.CON.layout=org.apache.log4j.PatternLayout -log4j.appender.CON.layout.ConversionPattern=%-5r %-5p [%t] %c{2} %x - %m%n \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/net/test/socketServer.lcf b/src/main/java/org/apache/log4j/net/test/socketServer.lcf deleted file mode 100644 index 574d644489..0000000000 --- a/src/main/java/org/apache/log4j/net/test/socketServer.lcf +++ /dev/null @@ -1,12 +0,0 @@ - -# ------------------------------------------------------------------- -# This config file is intended to be used by a SocketServer that logs -# events received from various clients on the console. -# ------------------------------------------------------------------- - -log4j.rootCategory=DEBUG, A1 -log4j.category.org.apache.log4j.net=DEBUG -log4j.appender.A1=org.apache.log4j.ConsoleAppender -log4j.appender.A1.layout=org.apache.log4j.PatternLayout -log4j.appender.A1.layout.ConversionPattern=%-5r %-5p [%t] %c{2} %x - %m%n - diff --git a/src/main/java/org/apache/log4j/net/test/syslog.lcf b/src/main/java/org/apache/log4j/net/test/syslog.lcf deleted file mode 100644 index 417ad6988e..0000000000 --- a/src/main/java/org/apache/log4j/net/test/syslog.lcf +++ /dev/null @@ -1,20 +0,0 @@ - -# ------------------------------------------------+ -# Set the host variable to match your environment | -# ------------------------------------------------+ -host=torino.qos.ch - - -log4j.rootCategory=DEBUG, A1 - -log4j.appender.A1=org.apache.log4j.net.SyslogAppender -log4j.appender.A1.SyslogHost=${host} - -log4j.appender.A1.layout=org.apache.log4j.PatternLayout - -# ----------------------------------------------------------------- -# The ConversionPattern should be terminated with a "\n" instead of -# the usual "%n" as the syslog host is most probably a unix machine. -# ----------------------------------------------------------------- -log4j.appender.A1.layout.ConversionPattern=%-5r %-5p [%t] %c{2} %x - %m\n - diff --git a/src/main/java/org/apache/log4j/net/test/syslogMin b/src/main/java/org/apache/log4j/net/test/syslogMin deleted file mode 100644 index ee0cea0ec9..0000000000 --- a/src/main/java/org/apache/log4j/net/test/syslogMin +++ /dev/null @@ -1,21 +0,0 @@ - - - -# Read the .functions file -. ../../test/.functions - -declare -i start=$1 - -setPERL - - echo "log4j.rootCategory= , testAppender" > $LCF - lecho "log4j.configDebug=true" - lecho "log4j.appender.testAppender=org.apache.log4j.net.SyslogAppender" - lecho "log4j.appender.testAppender.SyslogHost=localhost" - lecho "log4j.appender.testAppender.Facility=LOCAL0" - lecho "log4j.appender.testAppender.FacilityPrinting=" - lecho "log4j.appender.testAppender.layout=org.apache.log4j.TTCCLayout" - lecho "log4j.appender.testAppender.layout.DateFormat=NULL" - lecho "log4j.appender.testAppender.layout.TimeZone=" - - java org.apache.log4j.net.test.SyslogMin $LCF diff --git a/src/main/java/org/apache/log4j/nt/EventLogCategories.mc b/src/main/java/org/apache/log4j/nt/EventLogCategories.mc deleted file mode 100644 index f017900055..0000000000 --- a/src/main/java/org/apache/log4j/nt/EventLogCategories.mc +++ /dev/null @@ -1,46 +0,0 @@ -; -; Licensed to the Apache Software Foundation (ASF) under one -; or more contributor license agreements. See the NOTICE file -; distributed with this work for additional information -; regarding copyright ownership. The ASF licenses this file -; to you under the Apache License, Version 2.0 (the -; "License"); you may not use this file except in compliance -; with the License. You may obtain a copy of the License at -; -; http://www.apache.org/licenses/LICENSE-2.0 -; -; Unless required by applicable law or agreed to in writing, -; software distributed under the License is distributed on an -; "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -; KIND, either express or implied. See the License for the -; specific language governing permissions and limitations -; under the License. -; -MessageId=1 -Language=English -Trace -. -MessageId=2 -Language=English -Debug -. -MessageId=3 -Language=English -Info -. -MessageId=4 -Language=English -Warn -. -MessageId=5 -Language=English -Error -. -MessageId=6 -Language=English -Fatal -. -MessageId=0x1000 -Language=English -%1 -. diff --git a/src/main/java/org/apache/log4j/nt/MSG00001.bin b/src/main/java/org/apache/log4j/nt/MSG00001.bin deleted file mode 100644 index b6a1996851..0000000000 Binary files a/src/main/java/org/apache/log4j/nt/MSG00001.bin and /dev/null differ diff --git a/src/main/java/org/apache/log4j/nt/NTEventLogAppender.java b/src/main/java/org/apache/log4j/nt/NTEventLogAppender.java index d31a033dfe..9f80addfcb 100644 --- a/src/main/java/org/apache/log4j/nt/NTEventLogAppender.java +++ b/src/main/java/org/apache/log4j/nt/NTEventLogAppender.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -18,113 +19,102 @@ import org.apache.log4j.AppenderSkeleton; import org.apache.log4j.Layout; -import org.apache.log4j.PatternLayout; +import org.apache.log4j.TTCCLayout; +import org.apache.log4j.helpers.LogLog; import org.apache.log4j.spi.LoggingEvent; + /** Append to the NT event log system.

    WARNING This appender can only be installed and used on a Windows system. -

    Do not forget to place the file NTEventLogAppender.dll in a +

    Do not forget to place NTEventLogAppender.dll, + NTEventLogAppender.amd64.dll, NTEventLogAppender.ia64.dll + or NTEventLogAppender.x86.dll as appropriate in a directory that is on the PATH of the Windows system. Otherwise, you will get a java.lang.UnsatisfiedLinkError. @author Chris Taylor @author Jim Cakalic */ public class NTEventLogAppender extends AppenderSkeleton { - - static { - System.loadLibrary("NTEventLogAppender"); - } - private int _handle = 0; - private boolean dirty = true; + private String source = null; private String server = null; + public NTEventLogAppender() { this(null, null, null); } - public NTEventLogAppender(final String source) { + public NTEventLogAppender(String source) { this(null, source, null); } - public NTEventLogAppender(final String server, final String source) { + public NTEventLogAppender(String server, String source) { this(server, source, null); } - public NTEventLogAppender(final Layout layout) { + public NTEventLogAppender(Layout layout) { this(null, null, layout); } - public NTEventLogAppender(final String source, final Layout layout) { + public NTEventLogAppender(String source, Layout layout) { this(null, source, layout); } - public NTEventLogAppender( - final String server, final String source, final Layout layout) { - super(false); - this.server = server; - + public NTEventLogAppender(String server, String source, Layout layout) { if (source == null) { - this.source = "Log4j"; + source = "Log4j"; } - if (layout == null) { - this.layout = new PatternLayout("%d [%t] %p %c %x %m%n"); + this.layout = new TTCCLayout(); } else { this.layout = layout; } - activateOptions(); + try { + _handle = registerEventSource(server, source); + } catch (Exception e) { + e.printStackTrace(); + _handle = 0; + } } - public void close() { + public + void close() { // unregister ... } - public void activateOptions() { - if (dirty && (source != null)) { - dirty = false; - - if (_handle != 0) { - try { - deregisterEventSource(_handle); - } catch (Exception e) { - getLogger().error("Could not deregister event source.", e); - } - } - + public + void activateOptions() { + if (source != null) { try { - _handle = registerEventSource(server, source); - super.activateOptions(); + _handle = registerEventSource(server, source); } catch (Exception e) { - getLogger().error("Could not register event source.", e); - _handle = 0; + LogLog.error("Could not register event source.", e); + _handle = 0; } } } - public void append(final LoggingEvent event) { + + public void append(LoggingEvent event) { + StringBuffer sbuf = new StringBuffer(); sbuf.append(layout.format(event)); - - if (layout.ignoresThrowable()) { + if(layout.ignoresThrowable()) { String[] s = event.getThrowableStrRep(); - if (s != null) { - int len = s.length; - - for (int i = 0; i < len; i++) { - sbuf.append(s[i]); - } + int len = s.length; + for(int i = 0; i < len; i++) { + sbuf.append(s[i]); + } } } - // Normalize the log message level into the supported categories int nt_category = event.getLevel().toInt(); @@ -135,8 +125,9 @@ public void append(final LoggingEvent event) { reportEvent(_handle, sbuf.toString(), nt_category); } - public void finalize() { - super.finalize(); + + public + void finalize() { deregisterEventSource(_handle); _handle = 0; } @@ -145,25 +136,47 @@ public void finalize() { The Source option which names the source of the event. The current value of this constant is Source. */ - public void setSource(final String source) { + public + void setSource(String source) { this.source = source.trim(); - dirty = true; } - public String getSource() { + public + String getSource() { return source; } - /** - The NTEventLogAppender requires a layout. Hence, - this method always returns true. */ - public boolean requiresLayout() { +/** + The NTEventLogAppender requires a layout. Hence, + this method always returns true. */ + public + boolean requiresLayout() { return true; } - private native int registerEventSource(String server, String source); + native private int registerEventSource(String server, String source); + native private void reportEvent(int handle, String message, int level); + native private void deregisterEventSource(int handle); - private native void reportEvent(int handle, String message, int level); - - private native void deregisterEventSource(int handle); + static { + String[] archs; + try { + archs = new String[] { System.getProperty("os.arch")}; + } catch(SecurityException e) { + archs = new String[] { "amd64", "ia64", "x86"}; + } + boolean loaded = false; + for(int i = 0; i < archs.length; i++) { + try { + System.loadLibrary("NTEventLogAppender." + archs[i]); + loaded = true; + break; + } catch(java.lang.UnsatisfiedLinkError e) { + loaded = false; + } + } + if (!loaded) { + System.loadLibrary("NTEventLogAppender"); + } +} } diff --git a/src/main/java/org/apache/log4j/nt/NTEventLogAppender.rc b/src/main/java/org/apache/log4j/nt/NTEventLogAppender.rc deleted file mode 100644 index 8c09b42053..0000000000 --- a/src/main/java/org/apache/log4j/nt/NTEventLogAppender.rc +++ /dev/null @@ -1,125 +0,0 @@ -// -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -// -// -// Message file include -// -LANGUAGE 0x9,0x1 -1 11 MSG00001.bin -// Microsoft Visual C++ generated resource script. -// -#include "windows.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -//#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1, 2, 15, 1 - PRODUCTVERSION 1, 2, 15, 1 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "Apache Software Foundation" - VALUE "FileDescription", "Platform methods for NTEventLogAppender" - VALUE "FileVersion", "1, 2, 15, 1" - VALUE "InternalName", "NTEventLogAppender" - VALUE "LegalCopyright", "Copyright (C) 2005, Apache Software Foundation" - VALUE "OriginalFilename", "NTEventLogAppender.dll" - VALUE "ProductName", "log4j" - VALUE "ProductVersion", "1, 2, 15, 1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/src/main/java/org/apache/log4j/nt/nteventlog.cpp b/src/main/java/org/apache/log4j/nt/nteventlog.cpp deleted file mode 100644 index a134c9bfc4..0000000000 --- a/src/main/java/org/apache/log4j/nt/nteventlog.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NtEventLogAppender_h -#define NtEventLogAppender_h - -#ifdef __GNUC__ -typedef long long __int64; -#endif - -#include "org_apache_log4j_Priority.h" -#include "org_apache_log4j_nt_NTEventLogAppender.h" -#include -#include - - -/* - * Convert log4j Priority to an EventLog category. Each category is - * backed by a message resource so that proper category names will - * be displayed in the NT Event Viewer. - */ -WORD getCategory(jint priority) { - WORD category = 1; - if (priority >= org_apache_log4j_Priority_DEBUG_INT) { - category = 2; - if (priority >= org_apache_log4j_Priority_INFO_INT) { - category = 3; - if (priority >= org_apache_log4j_Priority_WARN_INT) { - category = 4; - if (priority >= org_apache_log4j_Priority_ERROR_INT) { - category = 5; - if (priority >= org_apache_log4j_Priority_FATAL_INT) { - category = 6; - } - } - } - } - } - return category; -} - -/* - * Convert log4j Priority to an EventLog type. The log4j package - * supports 8 defined priorites, but the NT EventLog only knows - * 3 event types of interest to us: ERROR, WARNING, and INFO. - */ -WORD getType(jint priority) { - WORD type = EVENTLOG_SUCCESS; - if (priority >= org_apache_log4j_Priority_INFO_INT) { - type = EVENTLOG_INFORMATION_TYPE; - if (priority >= org_apache_log4j_Priority_WARN_INT) { - type = EVENTLOG_WARNING_TYPE; - if (priority >= org_apache_log4j_Priority_ERROR_INT) { - type = EVENTLOG_ERROR_TYPE; - } - } - } - return type; -} - -HKEY regGetKey(wchar_t *subkey, DWORD *disposition) { - HKEY hkey = 0; - RegCreateKeyExW(HKEY_LOCAL_MACHINE, subkey, 0, NULL, - REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, - &hkey, disposition); - return hkey; -} - -void regSetString(HKEY hkey, wchar_t *name, wchar_t *value) { - RegSetValueExW(hkey, name, 0, REG_EXPAND_SZ, - (LPBYTE)value, (wcslen(value) + 1) * sizeof(wchar_t)); -} - -void regSetDword(HKEY hkey, wchar_t *name, DWORD value) { - RegSetValueExW(hkey, name, 0, REG_DWORD, (LPBYTE)&value, sizeof(DWORD)); -} - -/* - * Add this source with appropriate configuration keys to the registry. - */ -void addRegistryInfo(wchar_t *source) { - const wchar_t *prefix = L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\"; - DWORD disposition; - HKEY hkey = 0; - wchar_t subkey[256]; - - wcscpy(subkey, prefix); - wcscat(subkey, source); - hkey = regGetKey(subkey, &disposition); - if (disposition == REG_CREATED_NEW_KEY) { - HMODULE hmodule = GetModuleHandleW(L"NTEventLogAppender.dll"); - if (hmodule != NULL) { - wchar_t modpath[_MAX_PATH]; - DWORD modlen = GetModuleFileNameW(hmodule, modpath, _MAX_PATH - 1); - if (modlen > 0) { - modpath[modlen] = 0; - regSetString(hkey, L"EventMessageFile", modpath); - regSetString(hkey, L"CategoryMessageFile", modpath); - } - } - regSetDword(hkey, L"TypesSupported", (DWORD)7); - regSetDword(hkey, L"CategoryCount", (DWORD) 6); - } - RegCloseKey(hkey); - return; -} - -/* - * Class: org.apache.log4j.nt.NTEventLogAppender - * Method: registerEventSource - * Signature: (Ljava/lang/String;Ljava/lang/String;)I - */ -JNIEXPORT jint JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_registerEventSource( - JNIEnv *env, jobject java_this, jstring server, jstring source) { - - jchar *nserver = 0; - jchar *nsource = 0; - - if (server != 0) { - jsize serverLen = env->GetStringLength(server); - nserver = (jchar*) malloc((serverLen +1) * sizeof(jchar)); - env->GetStringRegion(server, 0, serverLen, nserver); - nserver[serverLen] = 0; - } - if (source != 0) { - jsize sourceLen = env->GetStringLength(source); - nsource = (jchar*) malloc((sourceLen +1) * sizeof(jchar)); - env->GetStringRegion(source, 0, sourceLen, nsource); - nsource[sourceLen] = 0; - } - addRegistryInfo((wchar_t*) nsource); - jint handle = (jint)RegisterEventSourceW((const wchar_t*) nserver, (const wchar_t*) nsource); - free(nserver); - free(nsource); - return handle; -} - -/* - * Class: org_apache_log4j_nt_NTEventLogAppender - * Method: reportEvent - * Signature: (ILjava/lang/String;I)V - */ -JNIEXPORT void JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_reportEvent( - JNIEnv *env, jobject java_this, jint handle, jstring jstr, jint priority) { - - jboolean localHandle = JNI_FALSE; - if (handle == 0) { - // Client didn't give us a handle so make a local one. - handle = (jint)RegisterEventSourceW(NULL, L"Log4j"); - localHandle = JNI_TRUE; - } - - // convert Java String to character array - jsize msgLen = env->GetStringLength(jstr); - jchar* msg = (jchar*) malloc((msgLen + 1) * sizeof(jchar)); - env->GetStringRegion(jstr, 0, msgLen, msg); - msg[msgLen] = 0; - - // This is the only message supported by the package. It is backed by - // a message resource which consists of just '%1' which is replaced - // by the string we just created. - const DWORD messageID = 0x1000; - ReportEventW((HANDLE)handle, getType(priority), - getCategory(priority), - messageID, NULL, 1, 0, (const wchar_t**) &msg, NULL); - - free((void *)msg); - if (localHandle == JNI_TRUE) { - // Created the handle here so free it here too. - DeregisterEventSource((HANDLE)handle); - } - return; -} - -/* - * Class: org_apache_log4j_nt_NTEventLogAppender - * Method: deregisterEventSource - * Signature: (I)V - */ -JNIEXPORT void JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_deregisterEventSource( -JNIEnv *env, -jobject java_this, -jint handle) -{ - DeregisterEventSource((HANDLE)handle); -} - - -#endif diff --git a/src/main/java/org/apache/log4j/nt/package.html b/src/main/java/org/apache/log4j/nt/package.html index 71bdf4cf48..a50567c301 100644 --- a/src/main/java/org/apache/log4j/nt/package.html +++ b/src/main/java/org/apache/log4j/nt/package.html @@ -1,4 +1,21 @@ + diff --git a/src/main/java/org/apache/log4j/or/DefaultRenderer.java b/src/main/java/org/apache/log4j/or/DefaultRenderer.java index c8b710a79b..7fe4ac6c9f 100644 --- a/src/main/java/org/apache/log4j/or/DefaultRenderer.java +++ b/src/main/java/org/apache/log4j/or/DefaultRenderer.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,7 +17,6 @@ package org.apache.log4j.or; - /** The default Renderer renders objects by calling their toString method. @@ -24,13 +24,19 @@ @author Ceki Gülcü @since 1.0 */ class DefaultRenderer implements ObjectRenderer { + DefaultRenderer() { } /** Render the object passed as parameter by calling its toString method. */ - public String doRender(Object o) { - return o.toString(); + public + String doRender(final Object o) { + try { + return o.toString(); + } catch(Exception ex) { + return ex.toString(); + } } -} +} diff --git a/src/main/java/org/apache/log4j/or/ObjectRenderer.java b/src/main/java/org/apache/log4j/or/ObjectRenderer.java index 4353590466..8ad99439e8 100644 --- a/src/main/java/org/apache/log4j/or/ObjectRenderer.java +++ b/src/main/java/org/apache/log4j/or/ObjectRenderer.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,15 +17,16 @@ package org.apache.log4j.or; - /** - * Implement this interface in order to render objects as strings. - * - * @author Ceki Gülcü - * @since 1.0 */ + Implement this interface in order to render objects as strings. + + @author Ceki Gülcü + @since 1.0 */ public interface ObjectRenderer { + /** Render the object passed as parameter as a String. */ - public String doRender(Object o); + public + String doRender(Object o); } diff --git a/src/main/java/org/apache/log4j/or/RendererMap.java b/src/main/java/org/apache/log4j/or/RendererMap.java index 3e233e2d05..6b3483e8a7 100644 --- a/src/main/java/org/apache/log4j/or/RendererMap.java +++ b/src/main/java/org/apache/log4j/or/RendererMap.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,83 +17,54 @@ package org.apache.log4j.or; +import org.apache.log4j.spi.RendererSupport; +import org.apache.log4j.helpers.LogLog; import org.apache.log4j.helpers.Loader; import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.spi.ComponentBase; -import org.apache.log4j.spi.RendererSupport; - import java.util.Hashtable; - /** Map class objects to an {@link ObjectRenderer}. @author Ceki Gülcü @since version 1.0 */ -public class RendererMap extends ComponentBase { - static ObjectRenderer defaultRenderer = new DefaultRenderer(); +public class RendererMap { + Hashtable map; - public RendererMap() { + static ObjectRenderer defaultRenderer = new DefaultRenderer(); + + public + RendererMap() { map = new Hashtable(); } /** - * Add a renderer to the current logger repository - * - * @param renderedClassName - * @param renderingClassName - */ - public void addRenderer(String renderedClassName, - String renderingClassName) { - getLogger().debug( - "Rendering class: [{}, Rendered class: [{}].", renderingClassName, - renderedClassName); - - ObjectRenderer renderer = - (ObjectRenderer) OptionConverter.instantiateByClassName( - renderingClassName, ObjectRenderer.class, null); - - if (renderer == null) { - getLogger().error( - "Could not instantiate renderer [" + renderingClassName + "]."); + Add a renderer to a hierarchy passed as parameter. + */ + static + public + void addRenderer(RendererSupport repository, String renderedClassName, + String renderingClassName) { + LogLog.debug("Rendering class: ["+renderingClassName+"], Rendered class: ["+ + renderedClassName+"]."); + ObjectRenderer renderer = (ObjectRenderer) + OptionConverter.instantiateByClassName(renderingClassName, + ObjectRenderer.class, + null); + if(renderer == null) { + LogLog.error("Could not instantiate renderer ["+renderingClassName+"]."); return; } else { try { - Class renderedClass = Loader.loadClass(renderedClassName); - if(repository != null && repository instanceof RendererSupport) { - ((RendererSupport)repository).setRenderer(renderedClass, renderer); - } - } catch (ClassNotFoundException e) { - getLogger().error("Could not find class [" + renderedClassName + "].", e); + Class renderedClass = Loader.loadClass(renderedClassName); + repository.setRenderer(renderedClass, renderer); + } catch(ClassNotFoundException e) { + LogLog.error("Could not find class ["+renderedClassName+"].", e); } } } - /** - * Add a renderer to a hierarchy passed as parameter - * - * @deprecated As of release 1.3, replaced by {@link #addRenderer(String,String)}. Left here only to provide binary compatibility with 1.2.xx and will be removed in a future release. - */ - static public void addRenderer(RendererSupport repository, String renderedClassName, - String renderingClassName) { - ObjectRenderer renderer = - (ObjectRenderer) OptionConverter.instantiateByClassName( - renderingClassName, ObjectRenderer.class, null); - - if (renderer == null) { - return; - } else { - try { - Class renderedClass = Loader.loadClass(renderedClassName); - if(repository != null) { - repository.setRenderer(renderedClass, renderer); - } - } catch (ClassNotFoundException e) { - ; - } - } - } /** Find the appropriate renderer for the class type of the @@ -100,25 +72,29 @@ static public void addRenderer(RendererSupport repository, String renderedClassN {@link #get(Class)} method. Once a renderer is found, it is applied on the object o and the result is returned as a {@link String}. */ - public String findAndRender(Object o) { - if (o == null) { - return null; + public + String findAndRender(Object o) { + if(o == null) { + return null; } else { - return get(o.getClass()).doRender(o); + return get(o.getClass()).doRender(o); } } + /** Syntactic sugar method that calls {@link #get(Class)} with the class of the object parameter. */ - public ObjectRenderer get(Object o) { - if (o == null) { - return null; + public + ObjectRenderer get(Object o) { + if(o == null) { + return null; } else { - return get(o.getClass()); + return get(o.getClass()); } } + /** Search the parents of clazz for a renderer. The renderer closest in the hierarchy will be returned. If no @@ -167,53 +143,60 @@ public ObjectRenderer get(Object o) { algorithm. However, the present algorithm should be acceptable in the vast majority of circumstances. - */ - public ObjectRenderer get(Class clazz) { + */ + public + ObjectRenderer get(Class clazz) { //System.out.println("\nget: "+clazz); ObjectRenderer r = null; - for (Class c = clazz; c != null; c = c.getSuperclass()) { + for(Class c = clazz; c != null; c = c.getSuperclass()) { //System.out.println("Searching for class: "+c); r = (ObjectRenderer) map.get(c); - if (r != null) { - return r; + if(r != null) { + return r; } r = searchInterfaces(c); - if (r != null) { + if(r != null) { return r; - } + } } return defaultRenderer; } ObjectRenderer searchInterfaces(Class c) { //System.out.println("Searching interfaces of class: "+c); + ObjectRenderer r = (ObjectRenderer) map.get(c); - if (r != null) { + if(r != null) { return r; } else { Class[] ia = c.getInterfaces(); - for (int i = 0; i < ia.length; i++) { - r = searchInterfaces(ia[i]); - if (r != null) { - return r; - } + for(int i = 0; i < ia.length; i++) { + r = searchInterfaces(ia[i]); + if(r != null) { + return r; + } } } return null; } - public ObjectRenderer getDefaultRenderer() { + + public + ObjectRenderer getDefaultRenderer() { return defaultRenderer; } - public void clear() { + + public + void clear() { map.clear(); } /** Register an {@link ObjectRenderer} for clazz. */ - public void put(Class clazz, ObjectRenderer or) { + public + void put(Class clazz, ObjectRenderer or) { map.put(clazz, or); } } diff --git a/src/main/java/org/apache/log4j/or/ThreadGroupRenderer.java b/src/main/java/org/apache/log4j/or/ThreadGroupRenderer.java index 6e0ad9da49..026ff4f815 100644 --- a/src/main/java/org/apache/log4j/or/ThreadGroupRenderer.java +++ b/src/main/java/org/apache/log4j/or/ThreadGroupRenderer.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -69,8 +70,12 @@ String doRender(Object o) { } return sbuf.toString(); } else { - // this is the best we can do - return o.toString(); + try { + // this is the best we can do + return o.toString(); + } catch(Exception ex) { + return ex.toString(); + } } } } diff --git a/src/main/java/org/apache/log4j/or/jms/MessageRenderer.java b/src/main/java/org/apache/log4j/or/jms/MessageRenderer.java index e2bbb3f6d2..e3140cbba5 100644 --- a/src/main/java/org/apache/log4j/or/jms/MessageRenderer.java +++ b/src/main/java/org/apache/log4j/or/jms/MessageRenderer.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,12 +17,12 @@ package org.apache.log4j.or.jms; +import org.apache.log4j.helpers.LogLog; import org.apache.log4j.or.ObjectRenderer; -import javax.jms.DeliveryMode; -import javax.jms.JMSException; import javax.jms.Message; - +import javax.jms.JMSException; +import javax.jms.DeliveryMode; /** Render javax.jms.Message objects. @@ -29,56 +30,67 @@ @author Ceki Gülcü @since 1.0 */ public class MessageRenderer implements ObjectRenderer { - public MessageRenderer() { + + public + MessageRenderer() { } + /** Render a {@link javax.jms.Message}. */ - public String doRender(Object o) { - if (o instanceof Message) { + public + String doRender(Object o) { + if(o instanceof Message) { StringBuffer sbuf = new StringBuffer(); Message m = (Message) o; try { - sbuf.append("DeliveryMode="); - switch (m.getJMSDeliveryMode()) { - case DeliveryMode.NON_PERSISTENT: - sbuf.append("NON_PERSISTENT"); - break; - case DeliveryMode.PERSISTENT: - sbuf.append("PERSISTENT"); - break; - default: - sbuf.append("UNKNOWN"); - } - sbuf.append(", CorrelationID="); - sbuf.append(m.getJMSCorrelationID()); - - sbuf.append(", Destination="); - sbuf.append(m.getJMSDestination()); - - sbuf.append(", Expiration="); - sbuf.append(m.getJMSExpiration()); - - sbuf.append(", MessageID="); - sbuf.append(m.getJMSMessageID()); - - sbuf.append(", Priority="); - sbuf.append(m.getJMSPriority()); - - sbuf.append(", Redelivered="); - sbuf.append(m.getJMSRedelivered()); - - sbuf.append(", ReplyTo="); - sbuf.append(m.getJMSReplyTo()); - - sbuf.append(", Timestamp="); - sbuf.append(m.getJMSTimestamp()); - - sbuf.append(", Type="); - sbuf.append(m.getJMSType()); - } catch (JMSException e) { - return o.toString(); + sbuf.append("DeliveryMode="); + switch(m.getJMSDeliveryMode()) { + case DeliveryMode.NON_PERSISTENT : + sbuf.append("NON_PERSISTENT"); + break; + case DeliveryMode.PERSISTENT : + sbuf.append("PERSISTENT"); + break; + default: sbuf.append("UNKNOWN"); + } + sbuf.append(", CorrelationID="); + sbuf.append(m.getJMSCorrelationID()); + + sbuf.append(", Destination="); + sbuf.append(m.getJMSDestination()); + + sbuf.append(", Expiration="); + sbuf.append(m.getJMSExpiration()); + + sbuf.append(", MessageID="); + sbuf.append(m.getJMSMessageID()); + + sbuf.append(", Priority="); + sbuf.append(m.getJMSPriority()); + + sbuf.append(", Redelivered="); + sbuf.append(m.getJMSRedelivered()); + + sbuf.append(", ReplyTo="); + sbuf.append(m.getJMSReplyTo()); + + sbuf.append(", Timestamp="); + sbuf.append(m.getJMSTimestamp()); + + sbuf.append(", Type="); + sbuf.append(m.getJMSType()); + + //Enumeration enum = m.getPropertyNames(); + //while(enum.hasMoreElements()) { + // String key = (String) enum.nextElement(); + // sbuf.append("; "+key+"="); + // sbuf.append(m.getStringProperty(key)); + //} + + } catch(JMSException e) { + LogLog.error("Could not parse Message.", e); } return sbuf.toString(); } else { diff --git a/src/main/java/org/apache/log4j/or/jms/package.html b/src/main/java/org/apache/log4j/or/jms/package.html index 595ba9bc60..d4db1c8442 100644 --- a/src/main/java/org/apache/log4j/or/jms/package.html +++ b/src/main/java/org/apache/log4j/or/jms/package.html @@ -1,3 +1,20 @@ + diff --git a/src/main/java/org/apache/log4j/or/package.html b/src/main/java/org/apache/log4j/or/package.html index 4565743073..17fd176c0b 100644 --- a/src/main/java/org/apache/log4j/or/package.html +++ b/src/main/java/org/apache/log4j/or/package.html @@ -1,4 +1,21 @@ + org.apache.log4j.or package diff --git a/src/main/java/org/apache/log4j/or/sax/AttributesRenderer.java b/src/main/java/org/apache/log4j/or/sax/AttributesRenderer.java index 13a433bcac..b5d088c2c3 100644 --- a/src/main/java/org/apache/log4j/or/sax/AttributesRenderer.java +++ b/src/main/java/org/apache/log4j/or/sax/AttributesRenderer.java @@ -1,9 +1,10 @@ /* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -54,7 +55,11 @@ String doRender(Object o) { } return sbuf.toString(); } else { - return o.toString(); + try { + return o.toString(); + } catch(Exception ex) { + return ex.toString(); + } } } } diff --git a/src/main/java/org/apache/log4j/or/sax/package.html b/src/main/java/org/apache/log4j/or/sax/package.html index 71bae3ebc8..a597141d5e 100644 --- a/src/main/java/org/apache/log4j/or/sax/package.html +++ b/src/main/java/org/apache/log4j/or/sax/package.html @@ -1,3 +1,20 @@ + diff --git a/src/main/java/org/apache/log4j/package.html b/src/main/java/org/apache/log4j/package.html index b2e044d8c7..3cf6e3e705 100644 --- a/src/main/java/org/apache/log4j/package.html +++ b/src/main/java/org/apache/log4j/package.html @@ -1,11 +1,28 @@ + -

    The main log4j package.

    +

    The main log4j package.


    diff --git a/src/main/java/org/apache/log4j/pattern/BridgePatternConverter.java b/src/main/java/org/apache/log4j/pattern/BridgePatternConverter.java index a7410c7b97..96068d52a6 100644 --- a/src/main/java/org/apache/log4j/pattern/BridgePatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/BridgePatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,10 +17,6 @@ package org.apache.log4j.pattern; -import org.apache.log4j.PatternLayout; -import org.apache.log4j.ULogger; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggerRepositoryEx; import org.apache.log4j.spi.LoggingEvent; import java.util.ArrayList; @@ -34,7 +31,6 @@ * * * @author Curt Arnold - * @since 1.3 * */ public final class BridgePatternConverter @@ -57,12 +53,9 @@ public final class BridgePatternConverter /** * Create a new instance. * @param pattern pattern, may not be null. - * @param repository logger repository, may be null. - * @param logger logger for internal logging. */ public BridgePatternConverter( - final String pattern, final LoggerRepository repository, - final ULogger logger) { + final String pattern) { next = null; handlesExceptions = false; @@ -70,15 +63,9 @@ public BridgePatternConverter( List fields = new ArrayList(); Map converterRegistry = null; - if (repository instanceof LoggerRepositoryEx) { - converterRegistry = - (Map) ((LoggerRepositoryEx) repository).getObject( - PatternLayout.PATTERN_RULE_REGISTRY); - } - PatternParser.parse( pattern, converters, fields, converterRegistry, - PatternParser.getPatternLayoutRules(), logger); + PatternParser.getPatternLayoutRules()); patternConverters = new LoggingEventPatternConverter[converters.size()]; patternFields = new FormattingInfo[converters.size()]; diff --git a/src/main/java/org/apache/log4j/pattern/BridgePatternParser.java b/src/main/java/org/apache/log4j/pattern/BridgePatternParser.java index 0d7d45e0d1..1c0d4e7238 100644 --- a/src/main/java/org/apache/log4j/pattern/BridgePatternParser.java +++ b/src/main/java/org/apache/log4j/pattern/BridgePatternParser.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,43 +17,25 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; -import org.apache.log4j.spi.LoggerRepository; - - /** * The class implements the pre log4j 1.3 org.apache.log4j.helpers.PatternConverter * contract by delegating to the log4j 1.3 pattern implementation. * * * @author Curt Arnold - * @since 1.3 * */ public final class BridgePatternParser extends org.apache.log4j.helpers.PatternParser { - /** - * Logger repository. - */ - private final LoggerRepository repository; - /** - * Internal logger. - */ - private final ULogger logger; /** * Create a new instance. * @param conversionPattern pattern, may not be null. - * @param repository repository, may be null. - * @param logger internal logger, may be null. */ public BridgePatternParser( - final String conversionPattern, final LoggerRepository repository, - final ULogger logger) { + final String conversionPattern) { super(conversionPattern); - this.repository = repository; - this.logger = logger; } /** @@ -60,6 +43,6 @@ public BridgePatternParser( * @return pattern converter. */ public org.apache.log4j.helpers.PatternConverter parse() { - return new BridgePatternConverter(pattern, repository, logger); + return new BridgePatternConverter(pattern); } } diff --git a/src/main/java/org/apache/log4j/pattern/CachedDateFormat.java b/src/main/java/org/apache/log4j/pattern/CachedDateFormat.java index 7d74f99c48..9a468aa4c0 100644 --- a/src/main/java/org/apache/log4j/pattern/CachedDateFormat.java +++ b/src/main/java/org/apache/log4j/pattern/CachedDateFormat.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -20,7 +21,6 @@ import java.text.FieldPosition; import java.text.NumberFormat; import java.text.ParsePosition; - import java.util.Date; import java.util.TimeZone; @@ -32,10 +32,12 @@ * the class will only use the cache if the * same value is requested. * - * @author Curt Arnold - * @since 1.3 */ -final class CachedDateFormat extends DateFormat { +public final class CachedDateFormat extends DateFormat { + /** + * Serialization version. + */ + private static final long serialVersionUID = 1; /** * Constant used to represent that there was no change * observed when changing the millisecond count. @@ -251,11 +253,10 @@ public StringBuffer format(long now, StringBuffer buf) { // If millisecond pattern was not unrecognized // (that is if it was found or milliseconds did not appear) // - if (millisecondStart != UNRECOGNIZED_MILLISECONDS) { + if (millisecondStart != UNRECOGNIZED_MILLISECONDS && // Check if the cache is still valid. // If the requested time is within the same integral second // as the last request and a shorter expiration was not requested. - if ( (now < (slotBegin + expiration)) && (now >= slotBegin) && (now < (slotBegin + 1000L))) { // @@ -272,7 +273,6 @@ public StringBuffer format(long now, StringBuffer buf) { buf.append(cache); return buf; - } } // diff --git a/src/main/java/org/apache/log4j/pattern/ClassNamePatternConverter.java b/src/main/java/org/apache/log4j/pattern/ClassNamePatternConverter.java index b807bd910f..7a24916fd4 100644 --- a/src/main/java/org/apache/log4j/pattern/ClassNamePatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/ClassNamePatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,37 +17,33 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; -import org.apache.log4j.spi.LoggingEvent; import org.apache.log4j.spi.LocationInfo; +import org.apache.log4j.spi.LoggingEvent; /** * Formats the class name of the site of the logging request. * * @author Ceki Gülcü - * @since 1.3 */ public final class ClassNamePatternConverter extends NamePatternConverter { /** * Private constructor. * @param options options, may be null. - * @param logger logger for diagnostic messages, may be null. */ private ClassNamePatternConverter( - final String[] options, final ULogger logger) { + final String[] options) { super("Class Name", "class name", options); } /** * Gets an instance of ClassNamePatternConverter. * @param options options, may be null. - * @param logger logger for diagnostic messages, may be null. * @return instance of pattern converter. */ public static ClassNamePatternConverter newInstance( - final String[] options, final ULogger logger) { - return new ClassNamePatternConverter(options, logger); + final String[] options) { + return new ClassNamePatternConverter(options); } /** diff --git a/src/main/java/org/apache/log4j/pattern/DatePatternConverter.java b/src/main/java/org/apache/log4j/pattern/DatePatternConverter.java index 5dee1a55d9..511fb70b29 100644 --- a/src/main/java/org/apache/log4j/pattern/DatePatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/DatePatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,12 +17,13 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; -import org.apache.log4j.helpers.Constants; +import org.apache.log4j.helpers.LogLog; import org.apache.log4j.spi.LoggingEvent; import java.text.SimpleDateFormat; - +import java.text.DateFormat; +import java.text.FieldPosition; +import java.text.ParsePosition; import java.util.Date; import java.util.TimeZone; @@ -30,20 +32,84 @@ * Convert and format the event's date in a StringBuffer. * * @author Ceki Gülcü - * @since 1.3 */ public final class DatePatternConverter extends LoggingEventPatternConverter { + /** + * ABSOLUTE string literal. + */ + private static final String ABSOLUTE_FORMAT = "ABSOLUTE"; + /** + * SimpleTimePattern for ABSOLUTE. + */ + private static final String ABSOLUTE_TIME_PATTERN = "HH:mm:ss,SSS"; + + + /** + * DATE string literal. + */ + private static final String DATE_AND_TIME_FORMAT = "DATE"; + /** + * SimpleTimePattern for DATE. + */ + private static final String DATE_AND_TIME_PATTERN = "dd MMM yyyy HH:mm:ss,SSS"; + + /** + * ISO8601 string literal. + */ + private static final String ISO8601_FORMAT = "ISO8601"; + /** + * SimpleTimePattern for ISO8601. + */ + private static final String ISO8601_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS"; /** * Date format. */ private final CachedDateFormat df; + /** + * This class wraps a DateFormat and forces the time zone to the + * default time zone before each format and parse request. + */ + private static class DefaultZoneDateFormat extends DateFormat { + /** + * Serialization version ID. + */ + private static final long serialVersionUID = 1; + /** + * Wrapped instance of DateFormat. + */ + private final DateFormat dateFormat; + + /** + * Construct new instance. + * @param format format, may not be null. + */ + public DefaultZoneDateFormat(final DateFormat format) { + dateFormat = format; + } + + /** + * @{inheritDoc} + */ + public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) { + dateFormat.setTimeZone(TimeZone.getDefault()); + return dateFormat.format(date, toAppendTo, fieldPosition); + } + + /** + * @{inheritDoc} + */ + public Date parse(String source, ParsePosition pos) { + dateFormat.setTimeZone(TimeZone.getDefault()); + return dateFormat.parse(source, pos); + } + } + /** * Private constructor. * @param options options, may be null. - * @param logger logger for diagnostic messages, may be null. */ - private DatePatternConverter(final String[] options, final ULogger logger) { + private DatePatternConverter(final String[] options) { super("Date", "date"); String patternOption; @@ -60,37 +126,37 @@ private DatePatternConverter(final String[] options, final ULogger logger) { if ( (patternOption == null) - || patternOption.equalsIgnoreCase(Constants.ISO8601_FORMAT)) { - pattern = Constants.ISO8601_PATTERN; - } else if (patternOption.equalsIgnoreCase(Constants.ABSOLUTE_FORMAT)) { - pattern = Constants.ABSOLUTE_TIME_PATTERN; - } else if (patternOption.equalsIgnoreCase(Constants.DATE_AND_TIME_FORMAT)) { - pattern = Constants.DATE_AND_TIME_PATTERN; + || patternOption.equalsIgnoreCase(ISO8601_FORMAT)) { + pattern = ISO8601_PATTERN; + } else if (patternOption.equalsIgnoreCase(ABSOLUTE_FORMAT)) { + pattern = ABSOLUTE_TIME_PATTERN; + } else if (patternOption.equalsIgnoreCase(DATE_AND_TIME_FORMAT)) { + pattern = DATE_AND_TIME_PATTERN; } else { pattern = patternOption; } int maximumCacheValidity = 1000; - SimpleDateFormat simpleFormat = null; + DateFormat simpleFormat = null; try { simpleFormat = new SimpleDateFormat(pattern); maximumCacheValidity = CachedDateFormat.getMaximumCacheValidity(pattern); } catch (IllegalArgumentException e) { - if (logger != null) { - logger.warn( + LogLog.warn( "Could not instantiate SimpleDateFormat with pattern " + patternOption, e); - } // default to the ISO8601 format - simpleFormat = new SimpleDateFormat(Constants.ISO8601_PATTERN); + simpleFormat = new SimpleDateFormat(ISO8601_PATTERN); } // if the option list contains a TZ option, then set it. if ((options != null) && (options.length > 1)) { - TimeZone tz = TimeZone.getTimeZone((String) options[1]); + TimeZone tz = TimeZone.getTimeZone(options[1]); simpleFormat.setTimeZone(tz); + } else { + simpleFormat = new DefaultZoneDateFormat(simpleFormat); } df = new CachedDateFormat(simpleFormat, maximumCacheValidity); @@ -99,12 +165,11 @@ private DatePatternConverter(final String[] options, final ULogger logger) { /** * Obtains an instance of pattern converter. * @param options options, may be null. - * @param logger logger, current ignored, may be null. * @return instance of pattern converter. */ public static DatePatternConverter newInstance( - final String[] options, final ULogger logger) { - return new DatePatternConverter(options, logger); + final String[] options) { + return new DatePatternConverter(options); } /** @@ -112,7 +177,7 @@ public static DatePatternConverter newInstance( */ public void format(final LoggingEvent event, final StringBuffer output) { synchronized(this) { - df.format(event.getTimeStamp(), output); + df.format(event.timeStamp, output); } } diff --git a/src/main/java/org/apache/log4j/pattern/FileDatePatternConverter.java b/src/main/java/org/apache/log4j/pattern/FileDatePatternConverter.java index 690969ca3d..1e08826e7f 100644 --- a/src/main/java/org/apache/log4j/pattern/FileDatePatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/FileDatePatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,16 +17,12 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; - - /** * Formats an date by delegating to DatePatternConverter. The default * date pattern for a %d specifier in a file name is different than * the %d pattern in pattern layout. * * @author Curt Arnold - * @since 1.3 */ public final class FileDatePatternConverter { /** @@ -37,16 +34,17 @@ private FileDatePatternConverter() { /** * Obtains an instance of pattern converter. * @param options options, may be null. - * @param logger logger, current ignored, may be null. * @return instance of pattern converter. */ public static PatternConverter newInstance( - final String[] options, final ULogger logger) { + final String[] options) { if ((options == null) || (options.length == 0)) { return DatePatternConverter.newInstance( - new String[] { "yyyy-MM-dd" }, logger); + new String[] { + "yyyy-MM-dd" + }); } - return DatePatternConverter.newInstance(options, logger); + return DatePatternConverter.newInstance(options); } } diff --git a/src/main/java/org/apache/log4j/pattern/FileLocationPatternConverter.java b/src/main/java/org/apache/log4j/pattern/FileLocationPatternConverter.java index 0ab904577f..14eb31c49a 100644 --- a/src/main/java/org/apache/log4j/pattern/FileLocationPatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/FileLocationPatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,16 +17,14 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; -import org.apache.log4j.spi.LoggingEvent; import org.apache.log4j.spi.LocationInfo; +import org.apache.log4j.spi.LoggingEvent; /** * Return the event's line location information in a StringBuffer. * * @author Ceki Gülcü - * @since 1.3 */ public final class FileLocationPatternConverter extends LoggingEventPatternConverter { @@ -45,11 +44,10 @@ private FileLocationPatternConverter() { /** * Obtains an instance of pattern converter. * @param options options, may be null. - * @param logger logger, current ignored, may be null. * @return instance of pattern converter. */ public static FileLocationPatternConverter newInstance( - final String[] options, final ULogger logger) { + final String[] options) { return INSTANCE; } diff --git a/src/main/java/org/apache/log4j/pattern/FormattingInfo.java b/src/main/java/org/apache/log4j/pattern/FormattingInfo.java index e2c876e89a..3fb127efc5 100644 --- a/src/main/java/org/apache/log4j/pattern/FormattingInfo.java +++ b/src/main/java/org/apache/log4j/pattern/FormattingInfo.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -26,7 +27,6 @@ * @author Ceki Gülcü * @author Curt Arnold * - * @since 1.3 */ public final class FormattingInfo { /** @@ -56,17 +56,46 @@ public final class FormattingInfo { */ private final boolean leftAlign; + /** + * Right truncation. + * @since 1.2.17 + */ + private final boolean rightTruncate; + + /** + * Creates new instance. + * @param leftAlign left align if true. + * @param minLength minimum length. + * @param maxLength maximum length. + * @deprecated since 1.2.17 + */ + public FormattingInfo( + final boolean leftAlign, + final int minLength, + final int maxLength) { + this.leftAlign = leftAlign; + this.minLength = minLength; + this.maxLength = maxLength; + this.rightTruncate = false; + } + /** * Creates new instance. * @param leftAlign left align if true. + * @param rightTruncate right truncate if true. * @param minLength minimum length. * @param maxLength maximum length. + * @since 1.2.17 */ public FormattingInfo( - final boolean leftAlign, final int minLength, final int maxLength) { + final boolean leftAlign, + final boolean rightTruncate, + final int minLength, + final int maxLength) { this.leftAlign = leftAlign; this.minLength = minLength; this.maxLength = maxLength; + this.rightTruncate = rightTruncate; } /** @@ -85,6 +114,15 @@ public boolean isLeftAligned() { return leftAlign; } + /** + * Determine if right truncated. + * @return true if right truncated. + * @since 1.2.17 + */ + public boolean isRightTruncated() { + return rightTruncate; + } + /** * Get minimum length. * @return minimum length. @@ -107,11 +145,15 @@ public int getMaxLength() { * @param fieldStart start of field in buffer. * @param buffer buffer to be modified. */ - public final void format(final int fieldStart, final StringBuffer buffer) { + public void format(final int fieldStart, final StringBuffer buffer) { final int rawLength = buffer.length() - fieldStart; if (rawLength > maxLength) { - buffer.delete(fieldStart, buffer.length() - maxLength); + if(rightTruncate) { + buffer.setLength(fieldStart + maxLength); + } else { + buffer.delete(fieldStart, buffer.length() - maxLength); + } } else if (rawLength < minLength) { if (leftAlign) { final int fieldEnd = buffer.length(); diff --git a/src/main/java/org/apache/log4j/pattern/FullLocationPatternConverter.java b/src/main/java/org/apache/log4j/pattern/FullLocationPatternConverter.java index e3a425ccc4..066016c074 100644 --- a/src/main/java/org/apache/log4j/pattern/FullLocationPatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/FullLocationPatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,16 +17,14 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; -import org.apache.log4j.spi.LoggingEvent; import org.apache.log4j.spi.LocationInfo; +import org.apache.log4j.spi.LoggingEvent; /** * Format the event's line location information. * * @author Ceki Gülcü - * @since 1.3 */ public final class FullLocationPatternConverter extends LoggingEventPatternConverter { @@ -45,11 +44,10 @@ private FullLocationPatternConverter() { /** * Obtains an instance of pattern converter. * @param options options, may be null. - * @param logger logger, current ignored, may be null. * @return instance of pattern converter. */ public static FullLocationPatternConverter newInstance( - final String[] options, final ULogger logger) { + final String[] options) { return INSTANCE; } @@ -60,7 +58,7 @@ public void format(final LoggingEvent event, final StringBuffer output) { LocationInfo locationInfo = event.getLocationInformation(); if (locationInfo != null) { - output.append(locationInfo.getFullInfo()); + output.append(locationInfo.fullInfo); } } } diff --git a/src/main/java/org/apache/log4j/pattern/IntegerPatternConverter.java b/src/main/java/org/apache/log4j/pattern/IntegerPatternConverter.java index fff906efde..f50feebf52 100644 --- a/src/main/java/org/apache/log4j/pattern/IntegerPatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/IntegerPatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,8 +17,6 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; - import java.util.Date; @@ -25,7 +24,6 @@ * Formats an integer. * * @author Curt Arnold - * @since 1.3 */ public final class IntegerPatternConverter extends PatternConverter { /** @@ -44,11 +42,10 @@ private IntegerPatternConverter() { /** * Obtains an instance of pattern converter. * @param options options, may be null. - * @param logger logger, current ignored, may be null. * @return instance of pattern converter. */ public static IntegerPatternConverter newInstance( - final String[] options, final ULogger logger) { + final String[] options) { return INSTANCE; } diff --git a/src/main/java/org/apache/log4j/pattern/LevelPatternConverter.java b/src/main/java/org/apache/log4j/pattern/LevelPatternConverter.java index 53658a9f86..3dbc6e6663 100644 --- a/src/main/java/org/apache/log4j/pattern/LevelPatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/LevelPatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -17,7 +18,6 @@ package org.apache.log4j.pattern; import org.apache.log4j.Level; -import org.apache.log4j.ULogger; import org.apache.log4j.spi.LoggingEvent; @@ -25,9 +25,13 @@ * Return the event's level in a StringBuffer. * * @author Ceki Gülcü - * @since 1.3 */ public final class LevelPatternConverter extends LoggingEventPatternConverter { + + /** + * Integer severity for Level.TRACE. + */ + private static final int TRACE_INT = 5000; /** * Singleton. */ @@ -44,11 +48,10 @@ private LevelPatternConverter() { /** * Obtains an instance of pattern converter. * @param options options, may be null. - * @param logger logger, current ignored, may be null. * @return instance of pattern converter. */ public static LevelPatternConverter newInstance( - final String[] options, final ULogger logger) { + final String[] options) { return INSTANCE; } @@ -67,7 +70,7 @@ public String getStyleClass(Object e) { int lint = ((LoggingEvent) e).getLevel().toInt(); switch (lint) { - case Level.TRACE_INT: + case TRACE_INT: return "level trace"; case Level.DEBUG_INT: diff --git a/src/main/java/org/apache/log4j/pattern/LineLocationPatternConverter.java b/src/main/java/org/apache/log4j/pattern/LineLocationPatternConverter.java index 9134a1340c..0a9dfd3945 100644 --- a/src/main/java/org/apache/log4j/pattern/LineLocationPatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/LineLocationPatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,16 +17,14 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; -import org.apache.log4j.spi.LoggingEvent; import org.apache.log4j.spi.LocationInfo; +import org.apache.log4j.spi.LoggingEvent; /** * Return the event's line location information in a StringBuffer. * * @author Ceki Gülcü - * @since 1.3 */ public final class LineLocationPatternConverter extends LoggingEventPatternConverter { @@ -45,11 +44,10 @@ private LineLocationPatternConverter() { /** * Obtains an instance of pattern converter. * @param options options, may be null. - * @param logger logger, current ignored, may be null. * @return instance of pattern converter. */ public static LineLocationPatternConverter newInstance( - final String[] options, final ULogger logger) { + final String[] options) { return INSTANCE; } diff --git a/src/main/java/org/apache/log4j/pattern/LineSeparatorPatternConverter.java b/src/main/java/org/apache/log4j/pattern/LineSeparatorPatternConverter.java index 1c13b46d70..a859870a3c 100644 --- a/src/main/java/org/apache/log4j/pattern/LineSeparatorPatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/LineSeparatorPatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -17,7 +18,6 @@ package org.apache.log4j.pattern; import org.apache.log4j.Layout; -import org.apache.log4j.ULogger; import org.apache.log4j.spi.LoggingEvent; @@ -25,7 +25,6 @@ * Formats a line separator. * * @author Ceki Gülcü - * @since 1.3 */ public final class LineSeparatorPatternConverter extends LoggingEventPatternConverter { @@ -51,11 +50,10 @@ private LineSeparatorPatternConverter() { /** * Obtains an instance of pattern converter. * @param options options, may be null. - * @param logger logger, current ignored, may be null. * @return instance of pattern converter. */ public static LineSeparatorPatternConverter newInstance( - final String[] options, final ULogger logger) { + final String[] options) { return INSTANCE; } diff --git a/src/main/java/org/apache/log4j/pattern/LiteralPatternConverter.java b/src/main/java/org/apache/log4j/pattern/LiteralPatternConverter.java index 9b1de590e5..b88b6f75c1 100644 --- a/src/main/java/org/apache/log4j/pattern/LiteralPatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/LiteralPatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -23,7 +24,6 @@ * Formats a string literal. * * @author Curt Arnold - * @since 1.3 * */ public final class LiteralPatternConverter extends LoggingEventPatternConverter { diff --git a/src/main/java/org/apache/log4j/pattern/LogEvent.java b/src/main/java/org/apache/log4j/pattern/LogEvent.java new file mode 100644 index 0000000000..703d3a57bb --- /dev/null +++ b/src/main/java/org/apache/log4j/pattern/LogEvent.java @@ -0,0 +1,603 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.pattern; + +import org.apache.log4j.Category; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.log4j.MDC; +import org.apache.log4j.NDC; +import org.apache.log4j.Priority; +import org.apache.log4j.helpers.Loader; +import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.spi.LocationInfo; +import org.apache.log4j.spi.LoggerRepository; +import org.apache.log4j.spi.RendererSupport; +import org.apache.log4j.spi.ThrowableInformation; + +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; +import java.util.Set; + +// Contributors: Nelson Minar +// Wolf Siberski +// Anders Kristensen + +/** + * This class is a copy of o.a.l.spi.LoggingEvent from + * log4j 1.2.15 which has been renamed to keep + * the same overall class name length to allow a + * serialization written with a prior instance of o.a.l.spi.LoggingEvent + * to be deserialized with this class just by mangling the class name + * in the byte stream. + * + */ +public class LogEvent implements java.io.Serializable { + + private static long startTime = System.currentTimeMillis(); + + /** Fully qualified name of the calling category class. */ + transient public final String fqnOfCategoryClass; + + /** + * The category of the logging event. This field is not serialized + * for performance reasons. + * + *

    It is set by the LoggingEvent constructor or set by a remote + * entity after deserialization. + * + * @deprecated This field will be marked as private or be completely + * removed in future releases. Please do not use it. + * */ + transient private Category logger; + + /** + *

    The category (logger) name. + * + * @deprecated This field will be marked as private in future + * releases. Please do not access it directly. Use the {@link + * #getLoggerName} method instead. + + * */ + final public String categoryName; + + /** + * Level of logging event. Level cannot be serializable because it + * is a flyweight. Due to its special seralization it cannot be + * declared final either. + * + *

    This field should not be accessed directly. You shoud use the + * {@link #getLevel} method instead. + * + * @deprecated This field will be marked as private in future + * releases. Please do not access it directly. Use the {@link + * #getLevel} method instead. + * */ + transient public Priority level; + + /** The nested diagnostic context (NDC) of logging event. */ + private String ndc; + + /** The mapped diagnostic context (MDC) of logging event. */ + private Hashtable mdcCopy; + + + /** Have we tried to do an NDC lookup? If we did, there is no need + * to do it again. Note that its value is always false when + * serialized. Thus, a receiving SocketNode will never use it's own + * (incorrect) NDC. See also writeObject method. */ + private boolean ndcLookupRequired = true; + + + /** Have we tried to do an MDC lookup? If we did, there is no need + * to do it again. Note that its value is always false when + * serialized. See also the getMDC and getMDCCopy methods. */ + private boolean mdcCopyLookupRequired = true; + + /** The application supplied message of logging event. */ + transient private Object message; + + /** The application supplied message rendered through the log4j + objet rendering mechanism.*/ + private String renderedMessage; + + /** The name of thread in which this logging event was generated. */ + private String threadName; + + + /** This + variable contains information about this event's throwable + */ + private ThrowableInformation throwableInfo; + + /** The number of milliseconds elapsed from 1/1/1970 until logging event + was created. */ + public final long timeStamp; + /** Location information for the caller. */ + private LocationInfo locationInfo; + + // Serialization + static final long serialVersionUID = -868428216207166145L; + + static final Integer[] PARAM_ARRAY = new Integer[1]; + static final String TO_LEVEL = "toLevel"; + static final Class[] TO_LEVEL_PARAMS = new Class[] {int.class}; + static final Hashtable methodCache = new Hashtable(3); // use a tiny table + + /** + Instantiate a LoggingEvent from the supplied parameters. + +

    Except {@link #timeStamp} all the other fields of + LoggingEvent are filled when actually needed. +

    + @param logger The logger generating this event. + @param level The level of this event. + @param message The message of this event. + @param throwable The throwable of this event. */ + public LogEvent(String fqnOfCategoryClass, Category logger, + Priority level, Object message, Throwable throwable) { + this.fqnOfCategoryClass = fqnOfCategoryClass; + this.logger = logger; + this.categoryName = logger.getName(); + this.level = level; + this.message = message; + if(throwable != null) { + this.throwableInfo = new ThrowableInformation(throwable); + } + timeStamp = System.currentTimeMillis(); + } + + /** + Instantiate a LoggingEvent from the supplied parameters. + +

    Except {@link #timeStamp} all the other fields of + LoggingEvent are filled when actually needed. +

    + @param logger The logger generating this event. + @param timeStamp the timestamp of this logging event + @param level The level of this event. + @param message The message of this event. + @param throwable The throwable of this event. */ + public LogEvent(String fqnOfCategoryClass, Category logger, + long timeStamp, Priority level, Object message, + Throwable throwable) { + this.fqnOfCategoryClass = fqnOfCategoryClass; + this.logger = logger; + this.categoryName = logger.getName(); + this.level = level; + this.message = message; + if(throwable != null) { + this.throwableInfo = new ThrowableInformation(throwable); + } + + this.timeStamp = timeStamp; + } + + /** + Create new instance. + @since 1.2.15 + @param fqnOfCategoryClass Fully qualified class name + of Logger implementation. + @param logger The logger generating this event. + @param timeStamp the timestamp of this logging event + @param level The level of this event. + @param message The message of this event. + @param threadName thread name + @param throwable The throwable of this event. + @param ndc Nested diagnostic context + @param info Location info + @param properties MDC properties + */ + public LogEvent(final String fqnOfCategoryClass, + final Logger logger, + final long timeStamp, + final Level level, + final Object message, + final String threadName, + final ThrowableInformation throwable, + final String ndc, + final LocationInfo info, + final java.util.Map properties) { + super(); + this.fqnOfCategoryClass = fqnOfCategoryClass; + this.logger = logger; + if (logger != null) { + categoryName = logger.getName(); + } else { + categoryName = null; + } + this.level = level; + this.message = message; + if(throwable != null) { + this.throwableInfo = throwable; + } + + this.timeStamp = timeStamp; + this.threadName = threadName; + ndcLookupRequired = false; + this.ndc = ndc; + this.locationInfo = info; + mdcCopyLookupRequired = false; + if (properties != null) { + mdcCopy = new java.util.Hashtable(properties); + } + } + + /** + Set the location information for this logging event. The collected + information is cached for future use. + */ + public LocationInfo getLocationInformation() { + if(locationInfo == null) { + locationInfo = new LocationInfo(new Throwable(), fqnOfCategoryClass); + } + return locationInfo; + } + + /** + * Return the level of this event. Use this form instead of directly + * accessing the level field. */ + public Level getLevel() { + return (Level) level; + } + + /** + * Return the name of the logger. Use this form instead of directly + * accessing the categoryName field. + */ + public String getLoggerName() { + return categoryName; + } + + /** + Return the message for this logging event. + +

    Before serialization, the returned object is the message + passed by the user to generate the logging event. After + serialization, the returned value equals the String form of the + message possibly after object rendering. + + @since 1.1 */ + public + Object getMessage() { + if(message != null) { + return message; + } else { + return getRenderedMessage(); + } + } + + /** + * This method returns the NDC for this event. It will return the + * correct content even if the event was generated in a different + * thread or even on a different machine. The {@link NDC#get} method + * should never be called directly. */ + public + String getNDC() { + if(ndcLookupRequired) { + ndcLookupRequired = false; + ndc = NDC.get(); + } + return ndc; + } + + + /** + Returns the the context corresponding to the key + parameter. If there is a local MDC copy, possibly because we are + in a logging server or running inside AsyncAppender, then we + search for the key in MDC copy, if a value is found it is + returned. Otherwise, if the search in MDC copy returns a null + result, then the current thread's MDC is used. + +

    Note that both the local MDC copy and the current + thread's MDC are searched. + + */ + public + Object getMDC(String key) { + Object r; + // Note the mdcCopy is used if it exists. Otherwise we use the MDC + // that is associated with the thread. + if(mdcCopy != null) { + r = mdcCopy.get(key); + if(r != null) { + return r; + } + } + return MDC.get(key); + } + + /** + Obtain a copy of this thread's MDC prior to serialization or + asynchronous logging. + */ + public + void getMDCCopy() { + if(mdcCopyLookupRequired) { + mdcCopyLookupRequired = false; + // the clone call is required for asynchronous logging. + // See also bug #5932. + Hashtable t = MDC.getContext(); + if(t != null) { + mdcCopy = (Hashtable) t.clone(); + } + } + } + + public + String getRenderedMessage() { + if(renderedMessage == null && message != null) { + if(message instanceof String) { + renderedMessage = (String) message; + } else { + LoggerRepository repository = logger.getLoggerRepository(); + + if(repository instanceof RendererSupport) { + RendererSupport rs = (RendererSupport) repository; + renderedMessage= rs.getRendererMap().findAndRender(message); + } else { + renderedMessage = message.toString(); + } + } + } + return renderedMessage; + } + + /** + Returns the time when the application started, in milliseconds + elapsed since 01.01.1970. */ + public static long getStartTime() { + return startTime; + } + + public + String getThreadName() { + if(threadName == null) { + threadName = (Thread.currentThread()).getName(); + } + return threadName; + } + + /** + Returns the throwable information contained within this + event. May be null if there is no such information. + +

    Note that the {@link Throwable} object contained within a + {@link ThrowableInformation} does not survive serialization. + + @since 1.1 */ + public + ThrowableInformation getThrowableInformation() { + return throwableInfo; + } + + /** + Return this event's throwable's string[] representaion. + */ + public + String[] getThrowableStrRep() { + + if(throwableInfo == null) { + return null; + } else { + return throwableInfo.getThrowableStrRep(); + } + } + + + private + void readLevel(ObjectInputStream ois) + throws java.io.IOException, ClassNotFoundException { + + int p = ois.readInt(); + try { + String className = (String) ois.readObject(); + if(className == null) { + level = Level.toLevel(p); + } else { + Method m = (Method) methodCache.get(className); + if(m == null) { + Class clazz = Loader.loadClass(className); + // Note that we use Class.getDeclaredMethod instead of + // Class.getMethod. This assumes that the Level subclass + // implements the toLevel(int) method which is a + // requirement. Actually, it does not make sense for Level + // subclasses NOT to implement this method. Also note that + // only Level can be subclassed and not Priority. + m = clazz.getDeclaredMethod(TO_LEVEL, TO_LEVEL_PARAMS); + methodCache.put(className, m); + } + PARAM_ARRAY[0] = new Integer(p); + level = (Level) m.invoke(null, PARAM_ARRAY); + } + } catch(Exception e) { + LogLog.warn("Level deserialization failed, reverting to default.", e); + level = Level.toLevel(p); + } + } + + private void readObject(ObjectInputStream ois) + throws java.io.IOException, ClassNotFoundException { + ois.defaultReadObject(); + readLevel(ois); + + // Make sure that no location info is available to Layouts + if(locationInfo == null) { + locationInfo = new LocationInfo(null, null); + } + } + + private + void writeObject(ObjectOutputStream oos) throws java.io.IOException { + // Aside from returning the current thread name the wgetThreadName + // method sets the threadName variable. + this.getThreadName(); + + // This sets the renders the message in case it wasn't up to now. + this.getRenderedMessage(); + + // This call has a side effect of setting this.ndc and + // setting ndcLookupRequired to false if not already false. + this.getNDC(); + + // This call has a side effect of setting this.mdcCopy and + // setting mdcLookupRequired to false if not already false. + this.getMDCCopy(); + + // This sets the throwable sting representation of the event throwable. + this.getThrowableStrRep(); + + oos.defaultWriteObject(); + + // serialize this event's level + writeLevel(oos); + } + + private + void writeLevel(ObjectOutputStream oos) throws java.io.IOException { + + oos.writeInt(level.toInt()); + + Class clazz = level.getClass(); + if(clazz == Level.class) { + oos.writeObject(null); + } else { + // writing directly the Class object would be nicer, except that + // serialized a Class object can not be read back by JDK + // 1.1.x. We have to resort to this hack instead. + oos.writeObject(clazz.getName()); + } + } + + /** + * Set value for MDC property. + * This adds the specified MDC property to the event. + * Access to the MDC is not synchronized, so this + * method should only be called when it is known that + * no other threads are accessing the MDC. + * @since 1.2.15 + * @param propName + * @param propValue + */ + public final void setProperty(final String propName, + final String propValue) { + if (mdcCopy == null) { + getMDCCopy(); + } + if (mdcCopy == null) { + mdcCopy = new Hashtable(); + } + mdcCopy.put(propName, propValue); + } + + /** + * Return a property for this event. The return value can be null. + * + * Equivalent to getMDC(String) in log4j 1.2. Provided + * for compatibility with log4j 1.3. + * + * @param key property name + * @return property value or null if property not set + * @since 1.2.15 + */ + public final String getProperty(final String key) { + Object value = getMDC(key); + String retval = null; + if (value != null) { + retval = value.toString(); + } + return retval; + } + + /** + * Check for the existence of location information without creating it + * (a byproduct of calling getLocationInformation). + * @return true if location information has been extracted. + * @since 1.2.15 + */ + public final boolean locationInformationExists() { + return (locationInfo != null); + } + + /** + * Getter for the event's time stamp. The time stamp is calculated starting + * from 1970-01-01 GMT. + * @return timestamp + * + * @since 1.2.15 + */ + public final long getTimeStamp() { + return timeStamp; + } + + /** + * Returns the set of the key values in the properties + * for the event. + * + * The returned set is unmodifiable by the caller. + * + * Provided for compatibility with log4j 1.3 + * + * @return Set an unmodifiable set of the property keys. + * @since 1.2.15 + */ + public Set getPropertyKeySet() { + return getProperties().keySet(); + } + + /** + * Returns the set of properties + * for the event. + * + * The returned set is unmodifiable by the caller. + * + * Provided for compatibility with log4j 1.3 + * + * @return Set an unmodifiable map of the properties. + * @since 1.2.15 + */ + public Map getProperties() { + getMDCCopy(); + Map properties; + if (mdcCopy == null) { + properties = new HashMap(); + } else { + properties = mdcCopy; + } + return Collections.unmodifiableMap(properties); + } + + /** + * Get the fully qualified name of the calling logger sub-class/wrapper. + * Provided for compatibility with log4j 1.3 + * @return fully qualified class name, may be null. + * @since 1.2.15 + */ + public String getFQNOfLoggerClass() { + return fqnOfCategoryClass; + } + + + +} diff --git a/src/main/java/org/apache/log4j/pattern/LoggerPatternConverter.java b/src/main/java/org/apache/log4j/pattern/LoggerPatternConverter.java index a8b22f7a15..7052a4e39c 100644 --- a/src/main/java/org/apache/log4j/pattern/LoggerPatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/LoggerPatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,7 +17,6 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; import org.apache.log4j.spi.LoggingEvent; @@ -25,37 +25,34 @@ * * @author Ceki Gülcü * - * @since 1.3 */ public final class LoggerPatternConverter extends NamePatternConverter { /** * Singleton. */ private static final LoggerPatternConverter INSTANCE = - new LoggerPatternConverter(null, null); + new LoggerPatternConverter(null); /** * Private constructor. * @param options options, may be null. - * @param logger logger for diagnostic messages, may be null. */ - private LoggerPatternConverter(final String[] options, final ULogger logger) { + private LoggerPatternConverter(final String[] options) { super("Logger", "logger", options); } /** * Obtains an instance of pattern converter. * @param options options, may be null. - * @param logger logger, current ignored, may be null. * @return instance of pattern converter. */ public static LoggerPatternConverter newInstance( - final String[] options, final ULogger logger) { + final String[] options) { if ((options == null) || (options.length == 0)) { return INSTANCE; } - return new LoggerPatternConverter(options, logger); + return new LoggerPatternConverter(options); } /** diff --git a/src/main/java/org/apache/log4j/pattern/LoggingEventPatternConverter.java b/src/main/java/org/apache/log4j/pattern/LoggingEventPatternConverter.java index a6fc85001d..d0fd4f408e 100644 --- a/src/main/java/org/apache/log4j/pattern/LoggingEventPatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/LoggingEventPatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -25,7 +26,6 @@ * * @author Curt Arnold * - * @since 1.3 */ public abstract class LoggingEventPatternConverter extends PatternConverter { /** diff --git a/src/main/java/org/apache/log4j/pattern/MessagePatternConverter.java b/src/main/java/org/apache/log4j/pattern/MessagePatternConverter.java index ff0f8d3669..c29f64a410 100644 --- a/src/main/java/org/apache/log4j/pattern/MessagePatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/MessagePatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,7 +17,6 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; import org.apache.log4j.spi.LoggingEvent; @@ -24,7 +24,6 @@ * Return the event's rendered message in a StringBuffer. * * @author Ceki Gülcü - * @since 1.3 */ public final class MessagePatternConverter extends LoggingEventPatternConverter { /** @@ -43,11 +42,10 @@ private MessagePatternConverter() { /** * Obtains an instance of pattern converter. * @param options options, may be null. - * @param logger logger, current ignored, may be null. * @return instance of pattern converter. */ public static MessagePatternConverter newInstance( - final String[] options, final ULogger logger) { + final String[] options) { return INSTANCE; } diff --git a/src/main/java/org/apache/log4j/pattern/MethodLocationPatternConverter.java b/src/main/java/org/apache/log4j/pattern/MethodLocationPatternConverter.java index bdc7ea9246..4d1b533973 100644 --- a/src/main/java/org/apache/log4j/pattern/MethodLocationPatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/MethodLocationPatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,16 +17,14 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; -import org.apache.log4j.spi.LoggingEvent; import org.apache.log4j.spi.LocationInfo; +import org.apache.log4j.spi.LoggingEvent; /** * Return the event's line location information in a StringBuffer. * * @author Ceki Gülcü - * @since 1.3 */ public final class MethodLocationPatternConverter extends LoggingEventPatternConverter { @@ -45,11 +44,10 @@ private MethodLocationPatternConverter() { /** * Obtains an instance of MethodLocationPatternConverter. * @param options options, may be null. - * @param logger logger, current ignored, may be null. * @return instance of MethodLocationPatternConverter. */ public static MethodLocationPatternConverter newInstance( - final String[] options, final ULogger logger) { + final String[] options) { return INSTANCE; } diff --git a/src/main/java/org/apache/log4j/pattern/NDCPatternConverter.java b/src/main/java/org/apache/log4j/pattern/NDCPatternConverter.java index 03184ce44e..9788cb1235 100644 --- a/src/main/java/org/apache/log4j/pattern/NDCPatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/NDCPatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,7 +17,6 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; import org.apache.log4j.spi.LoggingEvent; @@ -24,7 +24,6 @@ * Return the event's NDC in a StringBuffer. * * @author Ceki Gülcü - * @since 1.3 */ public final class NDCPatternConverter extends LoggingEventPatternConverter { /** @@ -43,11 +42,10 @@ private NDCPatternConverter() { /** * Obtains an instance of NDCPatternConverter. * @param options options, may be null. - * @param logger logger, current ignored, may be null. * @return instance of NDCPatternConverter. */ public static NDCPatternConverter newInstance( - final String[] options, final ULogger logger) { + final String[] options) { return INSTANCE; } diff --git a/src/main/java/org/apache/log4j/pattern/NameAbbreviator.java b/src/main/java/org/apache/log4j/pattern/NameAbbreviator.java index 8a9b81b4a3..b7e89a0cdd 100644 --- a/src/main/java/org/apache/log4j/pattern/NameAbbreviator.java +++ b/src/main/java/org/apache/log4j/pattern/NameAbbreviator.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -23,8 +24,6 @@ /** * NameAbbreviator generates abbreviated logger and class names. * - * @author Curt Arnold - * @since 1.3 */ public abstract class NameAbbreviator { /** @@ -36,8 +35,9 @@ public abstract class NameAbbreviator { * Gets an abbreviator. * * For example, "%logger{2}" will output only 2 elements of the logger name, + * %logger{-2} will drop 2 elements from the logger name, * "%logger{1.}" will output only the first character of the non-final elements in the name, - * "%logger(1~.2~} will output the first character of the first element, two characters of + * "%logger{1~.2~} will output the first character of the first element, two characters of * the second and subsequent elements and will use a tilde to indicate abbreviated characters. * * @param pattern abbreviation pattern. @@ -54,18 +54,29 @@ public static NameAbbreviator getAbbreviator(final String pattern) { } int i = 0; - - while ( - (i < trimmed.length()) && (trimmed.charAt(i) >= '0') - && (trimmed.charAt(i) <= '9')) { - i++; + if (trimmed.length() > 0) { + if (trimmed.charAt(0) == '-') { + i++; + } + for (; + (i < trimmed.length()) && + (trimmed.charAt(i) >= '0') && + (trimmed.charAt(i) <= '9'); + i++) { + } } + // // if all blanks and digits // if (i == trimmed.length()) { - return new MaxElementAbbreviator(Integer.parseInt(trimmed)); + int elements = Integer.parseInt(trimmed); + if (elements >= 0) { + return new MaxElementAbbreviator(elements); + } else { + return new DropElementAbbreviator(-elements); + } } ArrayList fragments = new ArrayList(5); @@ -174,8 +185,6 @@ public MaxElementAbbreviator(final int count) { * @param nameStart start of name to abbreviate. */ public void abbreviate(final int nameStart, final StringBuffer buf) { - int len = buf.length() - nameStart; - // We substract 1 from 'len' when assigning to 'end' to avoid out of // bounds exception in return r.substring(end+1, len). This can happen if // precision is 1 and the category name ends with a dot. @@ -194,6 +203,42 @@ public void abbreviate(final int nameStart, final StringBuffer buf) { } } + /** + * Abbreviator that drops starting path elements. + */ + private static class DropElementAbbreviator extends NameAbbreviator { + /** + * Maximum number of path elements to output. + */ + private final int count; + + /** + * Create new instance. + * @param count maximum number of path elements to output. + */ + public DropElementAbbreviator(final int count) { + this.count = count; + } + + /** + * Abbreviate name. + * @param buf buffer to append abbreviation. + * @param nameStart start of name to abbreviate. + */ + public void abbreviate(final int nameStart, final StringBuffer buf) { + int i = count; + for(int pos = buf.indexOf(".", nameStart); + pos != -1; + pos = buf.indexOf(".", pos + 1)) { + if(--i == 0) { + buf.delete(nameStart, pos + 1); + break; + } + } + } + } + + /** * Fragment of an pattern abbreviator. * diff --git a/src/main/java/org/apache/log4j/pattern/NamePatternConverter.java b/src/main/java/org/apache/log4j/pattern/NamePatternConverter.java index 04fa2e35e2..fbdd999c72 100644 --- a/src/main/java/org/apache/log4j/pattern/NamePatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/NamePatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -24,7 +25,6 @@ * @author Ceki Gülcü * @author Curt Arnold * - * @since 1.3 */ public abstract class NamePatternConverter extends LoggingEventPatternConverter { diff --git a/src/main/java/org/apache/log4j/pattern/PatternConverter.java b/src/main/java/org/apache/log4j/pattern/PatternConverter.java index a1c35b313b..21fb7cd39e 100644 --- a/src/main/java/org/apache/log4j/pattern/PatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/PatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -31,7 +32,6 @@ @author Chris Nokes @author Curt Arnold - @since 1.3 */ public abstract class PatternConverter { /** diff --git a/src/main/java/org/apache/log4j/pattern/PatternParser.java b/src/main/java/org/apache/log4j/pattern/PatternParser.java index 9ca7bcf348..901b0fefeb 100644 --- a/src/main/java/org/apache/log4j/pattern/PatternParser.java +++ b/src/main/java/org/apache/log4j/pattern/PatternParser.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,11 +17,10 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; import org.apache.log4j.helpers.Loader; +import org.apache.log4j.helpers.LogLog; import java.lang.reflect.Method; - import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -28,13 +28,12 @@ import java.util.Map; import java.util.Set; - // Contributors: Nelson Minar <(nelson@monkey.org> // Igor E. Poteryaev // Reinhard Deschler /** - * Most of the work of the {@link org.apache.log4j.PatternLayout} class + * Most of the work of the {@link org.apache.log4j.EnhancedPatternLayout} class * is delegated to the PatternParser class. *

    It is this class that parses conversion patterns and creates * a chained list of {@link PatternConverter PatternConverters}. @@ -45,7 +44,6 @@ * @author Paul Smith * @author Curt Arnold * - * @since 1.3 */ public final class PatternParser { /** @@ -79,7 +77,7 @@ public final class PatternParser { private static final int MAX_STATE = 5; /** - * Standard format specifiers for PatternLayout. + * Standard format specifiers for EnhancedPatternLayout. */ private static final Map PATTERN_LAYOUT_RULES; @@ -153,7 +151,7 @@ private PatternParser() { } /** - * Get standard format specifiers for PatternLayout. + * Get standard format specifiers for EnhancedPatternLayout. * @return read-only map of format converter classes keyed by format specifier strings. */ public static Map getPatternLayoutRules() { @@ -242,12 +240,10 @@ private static int extractOptions(String pattern, int i, List options) { * @param formattingInfos list to receive field specifiers corresponding to pattern converters. * @param converterRegistry map of user-supported pattern converters keyed by format specifier, may be null. * @param rules map of stock pattern converters keyed by format specifier. - * @param logger logger to receive parser warnings, may be null. */ public static void parse( final String pattern, final List patternConverters, - final List formattingInfos, final Map converterRegistry, final Map rules, - final ULogger logger) { + final List formattingInfos, final Map converterRegistry, final Map rules) { if (pattern == null) { throw new NullPointerException("pattern"); } @@ -308,11 +304,22 @@ public static void parse( case '-': formattingInfo = new FormattingInfo( - true, formattingInfo.getMinLength(), + true, + formattingInfo.isRightTruncated(), + formattingInfo.getMinLength(), formattingInfo.getMaxLength()); + break; + case '!': + formattingInfo = + new FormattingInfo( + formattingInfo.isLeftAligned(), + true, + formattingInfo.getMinLength(), + formattingInfo.getMaxLength()); break; + case '.': state = DOT_STATE; @@ -323,12 +330,14 @@ public static void parse( if ((c >= '0') && (c <= '9')) { formattingInfo = new FormattingInfo( - formattingInfo.isLeftAligned(), c - '0', + formattingInfo.isLeftAligned(), + formattingInfo.isRightTruncated(), + c - '0', formattingInfo.getMaxLength()); state = MIN_STATE; } else { i = finalizeConverter( - c, pattern, i, logger, currentLiteral, formattingInfo, + c, pattern, i, currentLiteral, formattingInfo, converterRegistry, rules, patternConverters, formattingInfos); // Next pattern is assumed to be a literal. @@ -347,13 +356,14 @@ public static void parse( formattingInfo = new FormattingInfo( formattingInfo.isLeftAligned(), + formattingInfo.isRightTruncated(), (formattingInfo.getMinLength() * 10) + (c - '0'), formattingInfo.getMaxLength()); } else if (c == '.') { state = DOT_STATE; } else { i = finalizeConverter( - c, pattern, i, logger, currentLiteral, formattingInfo, + c, pattern, i, currentLiteral, formattingInfo, converterRegistry, rules, patternConverters, formattingInfos); state = LITERAL_STATE; formattingInfo = FormattingInfo.getDefault(); @@ -368,15 +378,15 @@ public static void parse( if ((c >= '0') && (c <= '9')) { formattingInfo = new FormattingInfo( - formattingInfo.isLeftAligned(), formattingInfo.getMinLength(), + formattingInfo.isLeftAligned(), + formattingInfo.isRightTruncated(), + formattingInfo.getMinLength(), c - '0'); state = MAX_STATE; } else { - if (logger != null) { - logger.error( + LogLog.error( "Error occured in position " + i + ".\n Was expecting digit, instead got char \"" + c + "\"."); - } state = LITERAL_STATE; } @@ -389,11 +399,13 @@ public static void parse( if ((c >= '0') && (c <= '9')) { formattingInfo = new FormattingInfo( - formattingInfo.isLeftAligned(), formattingInfo.getMinLength(), + formattingInfo.isLeftAligned(), + formattingInfo.isRightTruncated(), + formattingInfo.getMinLength(), (formattingInfo.getMaxLength() * 10) + (c - '0')); } else { i = finalizeConverter( - c, pattern, i, logger, currentLiteral, formattingInfo, + c, pattern, i, currentLiteral, formattingInfo, converterRegistry, rules, patternConverters, formattingInfos); state = LITERAL_STATE; formattingInfo = FormattingInfo.getDefault(); @@ -421,14 +433,12 @@ public static void parse( * if converterId contains extra characters. * @param converterRegistry map of user-supported pattern converters keyed by format specifier, may be null. * @param rules map of stock pattern converters keyed by format specifier. - * @param logger logger to receive parser warnings, may be null. * @param options converter options. * @return converter or null. */ private static PatternConverter createConverter( final String converterId, final StringBuffer currentLiteral, - final Map converterRegistry, final Map rules, final List options, - final ULogger logger) { + final Map converterRegistry, final Map rules, final List options) { String converterName = converterId; Object converterObj = null; @@ -446,9 +456,7 @@ private static PatternConverter createConverter( } if (converterObj == null) { - if (logger != null) { - logger.error("Unrecognized format specifier [{}]", converterId); - } + LogLog.error("Unrecognized format specifier [" + converterId + "]"); return null; } @@ -462,19 +470,15 @@ private static PatternConverter createConverter( try { converterClass = Loader.loadClass((String) converterObj); } catch (ClassNotFoundException ex) { - if (logger != null) { - logger.warn( + LogLog.warn( "Class for conversion pattern %" + converterName + " not found", ex); - } return null; } } else { - if (logger != null) { - logger.warn( - "Bad map entry for conversion pattern %{}.", converterName); - } + LogLog.warn( + "Bad map entry for conversion pattern %" + converterName + "."); return null; } @@ -485,14 +489,13 @@ private static PatternConverter createConverter( converterClass.getMethod( "newInstance", new Class[] { - Class.forName("[Ljava.lang.String;"), - org.apache.log4j.ULogger.class + Class.forName("[Ljava.lang.String;") }); String[] optionsArray = new String[options.size()]; optionsArray = (String[]) options.toArray(optionsArray); Object newObj = - factory.invoke(null, new Object[] { optionsArray, logger }); + factory.invoke(null, new Object[] { optionsArray }); if (newObj instanceof PatternConverter) { currentLiteral.delete( @@ -502,16 +505,12 @@ private static PatternConverter createConverter( return (PatternConverter) newObj; } else { - if (logger != null) { - logger.warn( + LogLog.warn( "Class " + converterClass.getName() + " does not extend PatternConverter."); - } } } catch (Exception ex) { - if (logger != null) { - logger.error("Error creating converter for " + converterId, ex); - } + LogLog.error("Error creating converter for " + converterId, ex); try { // @@ -524,9 +523,7 @@ private static PatternConverter createConverter( return pc; } catch (Exception ex2) { - if (logger != null) { - logger.error("Error creating converter for " + converterId, ex2); - } + LogLog.error("Error creating converter for " + converterId, ex2); } } @@ -539,7 +536,6 @@ private static PatternConverter createConverter( * @param c initial character of format specifier. * @param pattern conversion pattern * @param i current position in conversion pattern. - * @param logger logger to receive warnings, may be null. * @param currentLiteral current literal. * @param formattingInfo current field specifier. * @param converterRegistry map of user-provided pattern converters keyed by format specifier, may be null. @@ -549,7 +545,7 @@ private static PatternConverter createConverter( * @return position after format specifier sequence. */ private static int finalizeConverter( - char c, String pattern, int i, final ULogger logger, + char c, String pattern, int i, final StringBuffer currentLiteral, final FormattingInfo formattingInfo, final Map converterRegistry, final Map rules, final List patternConverters, final List formattingInfos) { @@ -563,7 +559,7 @@ private static int finalizeConverter( PatternConverter pc = createConverter( - converterId, currentLiteral, converterRegistry, rules, options, logger); + converterId, currentLiteral, converterRegistry, rules, options); if (pc == null) { StringBuffer msg; @@ -580,9 +576,7 @@ private static int finalizeConverter( msg.append(Integer.toString(i)); msg.append(" in conversion pattern."); - if (logger != null) { - logger.error(msg.toString()); - } + LogLog.error(msg.toString()); patternConverters.add( new LiteralPatternConverter(currentLiteral.toString())); diff --git a/src/main/java/org/apache/log4j/pattern/PropertiesPatternConverter.java b/src/main/java/org/apache/log4j/pattern/PropertiesPatternConverter.java index 02335c1060..a55cf97edd 100644 --- a/src/main/java/org/apache/log4j/pattern/PropertiesPatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/PropertiesPatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,10 +17,11 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; import org.apache.log4j.spi.LoggingEvent; -import java.util.*; +import java.util.Iterator; +import java.util.Set; +import org.apache.log4j.helpers.*; /** @@ -31,7 +33,6 @@ * * @author Paul Smith * @author Ceki Gülcü - *@since 1.3 */ public final class PropertiesPatternConverter extends LoggingEventPatternConverter { @@ -43,10 +44,9 @@ public final class PropertiesPatternConverter /** * Private constructor. * @param options options, may be null. - * @param logger logger for diagnostic messages, may be null. */ private PropertiesPatternConverter( - final String[] options, final ULogger logger) { + final String[] options) { super( ((options != null) && (options.length > 0)) ? ("Property{" + options[0] + "}") : "Properties", "property"); @@ -61,12 +61,11 @@ private PropertiesPatternConverter( /** * Obtains an instance of PropertiesPatternConverter. * @param options options, may be null or first element contains name of property to format. - * @param logger logger, current ignored, may be null. * @return instance of PropertiesPatternConverter. */ public static PropertiesPatternConverter newInstance( - final String[] options, final ULogger logger) { - return new PropertiesPatternConverter(options, logger); + final String[] options) { + return new PropertiesPatternConverter(options); } /** @@ -78,19 +77,24 @@ public void format(final LoggingEvent event, final StringBuffer toAppendTo) { if (option == null) { toAppendTo.append("{"); - Set keySet = event.getPropertyKeySet(); - - for (Iterator i = keySet.iterator(); i.hasNext();) { - Object item = i.next(); - Object val = event.getProperty(item.toString()); - toAppendTo.append("{").append(item).append(",").append(val).append( - "}"); + try { + Set keySet = MDCKeySetExtractor.INSTANCE.getPropertyKeySet(event); + if (keySet != null) { + for (Iterator i = keySet.iterator(); i.hasNext();) { + Object item = i.next(); + Object val = event.getMDC(item.toString()); + toAppendTo.append("{").append(item).append(",").append(val).append( + "}"); + } + } + } catch(Exception ex) { + LogLog.error("Unexpected exception while extracting MDC keys", ex); } toAppendTo.append("}"); } else { // otherwise they just want a single key output - Object val = event.getProperty(option); + Object val = event.getMDC(option); if (val != null) { toAppendTo.append(val); diff --git a/src/main/java/org/apache/log4j/pattern/RelativeTimePatternConverter.java b/src/main/java/org/apache/log4j/pattern/RelativeTimePatternConverter.java index 973514ccae..007a29a72d 100644 --- a/src/main/java/org/apache/log4j/pattern/RelativeTimePatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/RelativeTimePatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,7 +17,6 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; import org.apache.log4j.spi.LoggingEvent; @@ -25,7 +25,6 @@ * class. * * @author Ceki Gülcü - * @since 1.3 */ public class RelativeTimePatternConverter extends LoggingEventPatternConverter { /** @@ -43,11 +42,10 @@ public RelativeTimePatternConverter() { /** * Obtains an instance of RelativeTimePatternConverter. * @param options options, currently ignored, may be null. - * @param logger logger, current ignored, may be null. * @return instance of RelativeTimePatternConverter. */ public static RelativeTimePatternConverter newInstance( - final String[] options, final ULogger logger) { + final String[] options) { return new RelativeTimePatternConverter(); } @@ -55,7 +53,7 @@ public static RelativeTimePatternConverter newInstance( * {@inheritDoc} */ public void format(final LoggingEvent event, final StringBuffer toAppendTo) { - long timestamp = event.getTimeStamp(); + long timestamp = event.timeStamp; if (!lastTimestamp.format(timestamp, toAppendTo)) { final String formatted = diff --git a/src/main/java/org/apache/log4j/pattern/SequenceNumberPatternConverter.java b/src/main/java/org/apache/log4j/pattern/SequenceNumberPatternConverter.java index 4afe4766d6..80126821da 100644 --- a/src/main/java/org/apache/log4j/pattern/SequenceNumberPatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/SequenceNumberPatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,7 +17,6 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; import org.apache.log4j.spi.LoggingEvent; @@ -24,7 +24,6 @@ * Formats the event sequence number. * * @author Ceki Gülcü - * @since 1.3 */ public class SequenceNumberPatternConverter extends LoggingEventPatternConverter { @@ -44,11 +43,10 @@ private SequenceNumberPatternConverter() { /** * Obtains an instance of SequencePatternConverter. * @param options options, currently ignored, may be null. - * @param logger logger, current ignored, may be null. * @return instance of SequencePatternConverter. */ public static SequenceNumberPatternConverter newInstance( - final String[] options, final ULogger logger) { + final String[] options) { return INSTANCE; } @@ -56,6 +54,6 @@ public static SequenceNumberPatternConverter newInstance( * {@inheritDoc} */ public void format(final LoggingEvent event, final StringBuffer toAppendTo) { - toAppendTo.append(Long.toString(event.getSequenceNumber())); + toAppendTo.append("0"); } } diff --git a/src/main/java/org/apache/log4j/pattern/ThreadPatternConverter.java b/src/main/java/org/apache/log4j/pattern/ThreadPatternConverter.java index 1cad971b3f..6b3e6c32d9 100644 --- a/src/main/java/org/apache/log4j/pattern/ThreadPatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/ThreadPatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,7 +17,6 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; import org.apache.log4j.spi.LoggingEvent; @@ -24,7 +24,6 @@ * Formats the event thread name. * * @author Ceki Gülcü - * @since 1.3 */ public class ThreadPatternConverter extends LoggingEventPatternConverter { /** @@ -43,11 +42,10 @@ private ThreadPatternConverter() { /** * Obtains an instance of ThreadPatternConverter. * @param options options, currently ignored, may be null. - * @param logger logger, current ignored, may be null. * @return instance of ThreadPatternConverter. */ public static ThreadPatternConverter newInstance( - final String[] options, final ULogger logger) { + final String[] options) { return INSTANCE; } diff --git a/src/main/java/org/apache/log4j/pattern/ThrowableInformationPatternConverter.java b/src/main/java/org/apache/log4j/pattern/ThrowableInformationPatternConverter.java index 3967465e5c..bf9c4b4457 100644 --- a/src/main/java/org/apache/log4j/pattern/ThrowableInformationPatternConverter.java +++ b/src/main/java/org/apache/log4j/pattern/ThrowableInformationPatternConverter.java @@ -1,9 +1,10 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -16,39 +17,48 @@ package org.apache.log4j.pattern; -import org.apache.log4j.ULogger; import org.apache.log4j.spi.LoggingEvent; import org.apache.log4j.spi.ThrowableInformation; /** - * Outputs the ThrowableInformation portion of the LoggingiEvent as a full stacktrace - * unless this converter's option is 'short', where it just outputs the first line of the trace. + * Outputs the ThrowableInformation portion of the LoggingEvent. + * By default, outputs the full stack trace. %throwable{none} + * or %throwable{0} suppresses the stack trace. %throwable{short} + * or %throwable{1} outputs just the first line. %throwable{n} + * will output n lines for a positive integer or drop the last + * -n lines for a negative integer. * * @author Paul Smith - * @since 1.3 * */ public class ThrowableInformationPatternConverter extends LoggingEventPatternConverter { + /** - * If "short", only first line of throwable report will be formatted. + * Maximum lines of stack trace to output. */ - private final String option; + private int maxLines = Integer.MAX_VALUE; /** * Private constructor. * @param options options, may be null. - * @param logger logger for diagnostic messages, may be null. */ private ThrowableInformationPatternConverter( - final String[] options, final ULogger logger) { + final String[] options) { super("Throwable", "throwable"); if ((options != null) && (options.length > 0)) { - option = options[0]; - } else { - option = null; + if("none".equals(options[0])) { + maxLines = 0; + } else if("short".equals(options[0])) { + maxLines = 1; + } else { + try { + maxLines = Integer.parseInt(options[0]); + } catch(NumberFormatException ex) { + } + } } } @@ -56,38 +66,34 @@ private ThrowableInformationPatternConverter( * Gets an instance of the class. * @param options pattern options, may be null. If first element is "short", * only the first line of the throwable will be formatted. - * @param logger logger, unused and may be null. * @return instance of class. */ public static ThrowableInformationPatternConverter newInstance( - final String[] options, final ULogger logger) { - return new ThrowableInformationPatternConverter(options, logger); + final String[] options) { + return new ThrowableInformationPatternConverter(options); } /** * {@inheritDoc} */ public void format(final LoggingEvent event, final StringBuffer toAppendTo) { - ThrowableInformation information = event.getThrowableInformation(); + if (maxLines != 0) { + ThrowableInformation information = event.getThrowableInformation(); - if (information != null) { - String[] stringRep = information.getThrowableStrRep(); + if (information != null) { + String[] stringRep = information.getThrowableStrRep(); - int length = 0; - - if (option == null) { - length = stringRep.length; - } else if (option.equals("full")) { - length = stringRep.length; - } else if (option.equals("short")) { - length = 1; - } else { - length = stringRep.length; - } + int length = stringRep.length; + if (maxLines < 0) { + length += maxLines; + } else if (length > maxLines) { + length = maxLines; + } - for (int i = 0; i < length; i++) { - String string = stringRep[i]; - toAppendTo.append(string).append("\n"); + for (int i = 0; i < length; i++) { + String string = stringRep[i]; + toAppendTo.append(string).append("\n"); + } } } } diff --git a/src/main/java/org/apache/log4j/pattern/package.html b/src/main/java/org/apache/log4j/pattern/package.html index a61bfdd3d9..1db8283dab 100644 --- a/src/main/java/org/apache/log4j/pattern/package.html +++ b/src/main/java/org/apache/log4j/pattern/package.html @@ -1,4 +1,21 @@ + diff --git a/src/main/java/org/apache/log4j/plugins/Pauseable.java b/src/main/java/org/apache/log4j/plugins/Pauseable.java deleted file mode 100644 index 6268ba38b7..0000000000 --- a/src/main/java/org/apache/log4j/plugins/Pauseable.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.plugins; - - -/** - * Instances of this interface can be paused, and resumed. - * - * @author Paul Smith (psmith@apache.org) - * - */ -public interface Pauseable { - /** - * Set paused state. - * @param paused new value - */ - void setPaused(boolean paused); - - /** - * Get paused state. - * @return paused state. - */ - boolean isPaused(); -} diff --git a/src/main/java/org/apache/log4j/plugins/Plugin.java b/src/main/java/org/apache/log4j/plugins/Plugin.java deleted file mode 100644 index e7b9b9ac17..0000000000 --- a/src/main/java/org/apache/log4j/plugins/Plugin.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.plugins; - -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.OptionHandler; - -import java.beans.PropertyChangeListener; - - -/** - * Defines the required interface for all Plugin objects. - *

    - *

    A plugin implements some specific functionality to extend - * the log4j framework. Each plugin is associated with a specific - * LoggerRepository, which it then uses/acts upon. The functionality - * of the plugin is up to the developer. - *

    - *

    Examples of plugins are Receiver and Watchdog. Receiver plugins - * allow for remote logging events to be received and processed by - * a repository as if the event was sent locally. Watchdog plugins - * allow for a repository to be reconfigured when some "watched" - * configuration data changes. - * - * @author Mark Womack (mwomack@apache.org) - * @author Nicko Cadell - * @author Paul Smith (psmith@apache.org) - * @since 1.3 - */ -public interface Plugin extends OptionHandler { - /** - * Gets the name of the plugin. - * - * @return String the name of the plugin. - */ - String getName(); - - /** - * Sets the name of the plugin. - * - * @param name the name of the plugin. - */ - void setName(String name); - - /** - * Gets the logger repository for this plugin. - * - * @return the logger repository to which this plugin is attached. - */ - LoggerRepository getLoggerRepository(); - - /** - * Sets the logger repository used by this plugin. This - * repository will be used by the plugin functionality. - * - * @param repository the logger repository to attach this plugin to. - */ - void setLoggerRepository(LoggerRepository repository); - - /** - * Adds a PropertyChangeListener to this instance which is - * notified only by changes of the property with name propertyName. - * - * @param propertyName - * the name of the property in standard JavaBean syntax - * (e.g. for setName(), property="name") - * @param l listener - */ - void addPropertyChangeListener( - String propertyName, PropertyChangeListener l); - - /** - * Adds a PropertyChangeListener that will be notified of all property - * changes. - * - * @param l The listener to add. - */ - void addPropertyChangeListener(PropertyChangeListener l); - - /** - * Removes a specific PropertyChangeListener from this instances - * registry that has been mapped to be notified of all property - * changes. - * - * @param l The listener to remove. - */ - void removePropertyChangeListener(PropertyChangeListener l); - - /** - * Removes a specific PropertyChangeListener from this instance's - * registry which has been previously registered to be notified - * of only a specific property change. - * - * @param propertyName property name, may not be null. - * @param l listener to be removed. - */ - void removePropertyChangeListener( - String propertyName, PropertyChangeListener l); - - /** - * True if the plugin is active and running. - * - * @return boolean true if the plugin is currently active. - */ - boolean isActive(); - - /** - * Returns true if the testPlugin is considered to be "equivalent" to the - * this plugin. The equivalency test is at the discretion of the plugin - * implementation. The PluginRegistry will use this method when starting - * new plugins to see if a given plugin is considered equivalent to an - * already running plugin with the same name. If they are considered to - * be equivalent, the currently running plugin will be left in place, and - * the new plugin will not be started. - *

    - * It is possible to override the equals() method, however this has - * more meaning than is required for this simple test and would also - * require the overriding of the hashCode() method as well. All of this - * is more work than is needed, so this simple method is used instead. - * - * @param testPlugin The plugin to test equivalency against. - * @return Returns true if testPlugin is considered to be equivelent. - */ - boolean isEquivalent(Plugin testPlugin); - - /** - * Call when the plugin should be stopped. - */ - void shutdown(); -} diff --git a/src/main/java/org/apache/log4j/plugins/PluginConfigurator.java b/src/main/java/org/apache/log4j/plugins/PluginConfigurator.java deleted file mode 100644 index e766490904..0000000000 --- a/src/main/java/org/apache/log4j/plugins/PluginConfigurator.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.plugins; - -/** - * This class is an alias for org.apache.log4j.xml.DOMConfigurator - * provided so Chainsaw can compile against both log4j 1.2 - * and log4j 1.3. In log4j 1.2, configuration of plugins - * requires extending DOMConfigurator. - */ -public final class PluginConfigurator extends - org.apache.log4j.xml.DOMConfigurator { - -} diff --git a/src/main/java/org/apache/log4j/plugins/PluginEvent.java b/src/main/java/org/apache/log4j/plugins/PluginEvent.java deleted file mode 100644 index 184303443d..0000000000 --- a/src/main/java/org/apache/log4j/plugins/PluginEvent.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.plugins; - -import java.util.EventObject; - - -/** - * All Plugin events are encapsulated in this class, which - * simply contains the source Plugin, but may in future include more - * information. - * - * @author Paul Smith - */ -public class PluginEvent extends EventObject { - /** - * @param source The source plugin of the event - */ - PluginEvent(final Plugin source) { - super(source); - } - - /** - * Returns the source Plugin of this event, which is simple - * the getSource() method casted to Plugin for convenience. - * - * @return Plugin source of this event - */ - public Plugin getPlugin() { - return (Plugin) getSource(); - } -} diff --git a/src/main/java/org/apache/log4j/plugins/PluginListener.java b/src/main/java/org/apache/log4j/plugins/PluginListener.java deleted file mode 100644 index 11f628eaa7..0000000000 --- a/src/main/java/org/apache/log4j/plugins/PluginListener.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - */ -package org.apache.log4j.plugins; - -import java.util.EventListener; - - -/** - * PluginListeners are notified when plugins are started or stopped - * by the PluginRegistry. - * - * @author Paul Smith (psmith@apache.org) - */ -public interface PluginListener extends EventListener { - /** - * Notification that plugin has started. - * @param e event - */ - void pluginStarted(PluginEvent e); - - /** - * Notification that plugin has stopped. - * @param e event - */ - void pluginStopped(PluginEvent e); -} diff --git a/src/main/java/org/apache/log4j/plugins/PluginRegistry.java b/src/main/java/org/apache/log4j/plugins/PluginRegistry.java deleted file mode 100644 index ed1ab0ec29..0000000000 --- a/src/main/java/org/apache/log4j/plugins/PluginRegistry.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.plugins; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggerRepositoryEx; -import org.apache.log4j.spi.LoggerRepositoryEventListener; - - -/** - * This is a registry for Plugin instances. It provides methods to - * start and stop plugin objects individually and to stop all - * plugins for a repository. - * - * @author Mark Womack - * @author Paul Smith - * @since 1.3 - */ -public final class PluginRegistry { - /** - * The pluginMap is keyed by plugin name and contains plugins as values. - * key=plugin.getName, value=plugin - */ - private final Map pluginMap; - /** - * Logger repository. - */ - private final LoggerRepositoryEx loggerRepository; - - /** - * the listener used to listen for repository events. - */ - private final RepositoryListener listener = new RepositoryListener(); - /** - * List of listeners. - */ - private final List listenerList = - Collections.synchronizedList(new ArrayList()); - - /** - * Creates a new instance. - * @param repository logger repository. - */ - public PluginRegistry(final LoggerRepositoryEx repository) { - super(); - pluginMap = new HashMap(); - this.loggerRepository = repository; - this.loggerRepository.addLoggerRepositoryEventListener(listener); - } - - /** - * Get logger repository. - * @return logger repository. - */ - public LoggerRepositoryEx getLoggerRepository() { - return loggerRepository; - } - - - /** - * Returns true if the specified name is already taken by - * an existing Plugin registered within the scope of the specified - * LoggerRepository. - * - * @param name The name to check the repository for - * @return true if the name is already in use, otherwise false - */ - public boolean pluginNameExists(final String name) { - synchronized (pluginMap) { - return pluginMap.containsKey(name); - } - } - - - /** - * Adds a plugin to the plugin registry. - * If a plugin with the same name exists - * already, it is shutdown and removed. - * - * @param plugin the plugin to add. - */ - public void addPlugin(final Plugin plugin) { - // put plugin into the repository's reciever map - synchronized (pluginMap) { - String name = plugin.getName(); - - // make sure the plugin has reference to repository - plugin.setLoggerRepository(getLoggerRepository()); - - Plugin existingPlugin = (Plugin) pluginMap.get(name); - if (existingPlugin != null) { - existingPlugin.shutdown(); - } - - // put the new plugin into the map - pluginMap.put(name, plugin); - firePluginStarted(plugin); - } - } - - - /** - * Calls the pluginStarted method on every registered PluginListener. - * - * @param plugin The plugin that has been started. - */ - private void firePluginStarted(final Plugin plugin) { - PluginEvent e = null; - synchronized (listenerList) { - for (Iterator iter = listenerList.iterator(); iter.hasNext();) { - PluginListener l = (PluginListener) iter.next(); - if (e == null) { - e = new PluginEvent(plugin); - } - l.pluginStarted(e); - } - } - } - - - /** - * Calls the pluginStopped method for every registered PluginListner. - * - * @param plugin The plugin that has been stopped. - */ - private void firePluginStopped(final Plugin plugin) { - PluginEvent e = null; - synchronized (listenerList) { - for (Iterator iter = listenerList.iterator(); iter.hasNext();) { - PluginListener l = (PluginListener) iter.next(); - if (e == null) { - e = new PluginEvent(plugin); - } - l.pluginStopped(e); - } - } - } - - - /** - * Returns all the plugins for a given repository. - * - * @return List list of plugins from the repository. - */ - public List getPlugins() { - synchronized (pluginMap) { - List pluginList = new ArrayList(pluginMap.size()); - Iterator iter = pluginMap.values().iterator(); - - while (iter.hasNext()) { - pluginList.add(iter.next()); - } - return pluginList; - } - } - - - /** - * Returns all the plugins for a given repository that are instances - * of a certain class. - * - * @param pluginClass the class the plugin must implement to be selected. - * @return List list of plugins from the repository. - */ - public List getPlugins(final Class pluginClass) { - synchronized (pluginMap) { - List pluginList = new ArrayList(pluginMap.size()); - Iterator iter = pluginMap.values().iterator(); - - while (iter.hasNext()) { - Object plugin = iter.next(); - - if (pluginClass.isInstance(plugin)) { - pluginList.add(plugin); - } - } - return pluginList; - } - } - - - /** - * Stops a plugin by plugin name and repository. - * - * @param pluginName the name of the plugin to stop. - * @return Plugin the plugin, if stopped, or null if the - * the plugin was not found in the registry. - */ - public Plugin stopPlugin(final String pluginName) { - synchronized (pluginMap) { - Plugin plugin = (Plugin) pluginMap.get(pluginName); - - if (plugin == null) { - return null; - } - - // shutdown the plugin - plugin.shutdown(); - - // remove it from the plugin map - pluginMap.remove(pluginName); - firePluginStopped(plugin); - - // return it for future use - return plugin; - } - } - - /** - * Stops all plugins in the given logger repository. - */ - public void stopAllPlugins() { - synchronized (pluginMap) { - // remove the listener for this repository - loggerRepository.removeLoggerRepositoryEventListener(listener); - - Iterator iter = pluginMap.values().iterator(); - - while (iter.hasNext()) { - Plugin plugin = (Plugin) iter.next(); - plugin.shutdown(); - firePluginStopped(plugin); - } - } - } - - - /** - * Adds a PluginListener to this registry to be notified - * of PluginEvents. - * - * @param l PluginListener to add to this registry - */ - public void addPluginListener(final PluginListener l) { - listenerList.add(l); - } - - - /** - * Removes a particular PluginListener from this registry - * such that it will no longer be notified of PluginEvents. - * - * @param l PluginListener to remove - */ - public void removePluginListener(final PluginListener l) { - listenerList.remove(l); - } - - /** - * Internal class used to handle listener events from repositories. - */ - private class RepositoryListener implements LoggerRepositoryEventListener { - /** - * Stops all plugins associated with the repository being reset. - * - * @param repository the repository that was reset. - */ - public void configurationResetEvent(final LoggerRepository repository) { - PluginRegistry.this.stopAllPlugins(); - } - - - /** - * Called when the repository configuration is changed. - * - * @param repository the repository that was changed. - */ - public void configurationChangedEvent( - final LoggerRepository repository) { - // do nothing with this event - } - - - /** - * Stops all plugins associated with the repository being shutdown. - * - * @param repository the repository being shutdown. - */ - public void shutdownEvent(final LoggerRepository repository) { - PluginRegistry.this.stopAllPlugins(); - } - } -} diff --git a/src/main/java/org/apache/log4j/plugins/PluginSkeleton.java b/src/main/java/org/apache/log4j/plugins/PluginSkeleton.java deleted file mode 100644 index 6d23282f8e..0000000000 --- a/src/main/java/org/apache/log4j/plugins/PluginSkeleton.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.plugins; - -import org.apache.log4j.spi.ComponentBase; -import org.apache.log4j.spi.LoggerRepository; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; - - -/** - * A convienent abstract class for plugin subclasses that implements - * the basic methods of the Plugin interface. Subclasses are required - * to implement the isActive(), activateOptions(), and shutdown() - * methods. - *

    - *

    Developers are not required to subclass PluginSkeleton to - * develop their own plugins (they are only required to implement the - * Plugin interface), but it provides a convenient base class to start - * from. - *

    - * Contributors: Nicko Cadell - * - * @author Mark Womack (mwomack@apache.org) - * @author Paul Smith (psmith@apache.org) - * @since 1.3 - */ -public abstract class PluginSkeleton extends ComponentBase implements Plugin { - /** - * Name of this plugin. - */ - protected String name = ""; - - /** - * Active state of plugin. - */ - protected boolean active; - - /** - * This is a delegate that does all the PropertyChangeListener - * support. - */ - private PropertyChangeSupport propertySupport = - new PropertyChangeSupport(this); - - /** - * Construct new instance. - */ - protected PluginSkeleton() { - super(); - } - - /** - * Gets the name of the plugin. - * - * @return String the name of the plugin. - */ - public String getName() { - return name; - } - - /** - * Sets the name of the plugin and notifies - * PropertyChangeListeners of the change. - * - * @param newName the name of the plugin to set. - */ - public void setName(final String newName) { - String oldName = this.name; - this.name = newName; - propertySupport.firePropertyChange("name", oldName, this.name); - } - - /** - * Gets the logger repository for this plugin. - * - * @return LoggerRepository the logger repository this plugin will affect. - */ - public LoggerRepository getLoggerRepository() { - return repository; - } - - /** - * Sets the logger repository used by this plugin and notifies a - * relevant PropertyChangeListeners registered. This - * repository will be used by the plugin functionality. - * - * @param repository the logger repository that this plugin should affect. - */ - public void setLoggerRepository(final LoggerRepository repository) { - Object oldValue = this.repository; - this.repository = repository; - firePropertyChange("loggerRepository", oldValue, this.repository); - } - - /** - * Returns whether this plugin is Active or not. - * - * @return true/false - */ - public synchronized boolean isActive() { - return active; - } - - /** - * Returns true if the plugin has the same name and logger repository as the - * testPlugin passed in. - * - * @param testPlugin The plugin to test equivalency against. - * @return Returns true if testPlugin is considered to be equivalent. - */ - public boolean isEquivalent(final Plugin testPlugin) { - return (repository == testPlugin.getLoggerRepository()) - && ((this.name == null && testPlugin.getName() == null) - || (this.name != null - && name.equals(testPlugin.getName()))) - && this.getClass().equals(testPlugin.getClass()); - } - - /** - * Add property change listener. - * @param listener listener. - */ - public final void addPropertyChangeListener( - final PropertyChangeListener listener) { - propertySupport.addPropertyChangeListener(listener); - } - - /** - * Add property change listener for one property only. - * @param propertyName property name. - * @param listener listener. - */ - public final void addPropertyChangeListener( - final String propertyName, - final PropertyChangeListener listener) { - propertySupport.addPropertyChangeListener(propertyName, listener); - } - - /** - * Remove property change listener. - * @param listener listener. - */ - public final void removePropertyChangeListener( - final PropertyChangeListener listener) { - propertySupport.removePropertyChangeListener(listener); - } - - /** - * Remove property change listener on a specific property. - * @param propertyName property name. - * @param listener listener. - */ - public final void removePropertyChangeListener( - final String propertyName, - final PropertyChangeListener listener) { - propertySupport.removePropertyChangeListener(propertyName, listener); - } - - /** - * Fire a property change event to appropriate listeners. - * @param evt change event. - */ - protected final void firePropertyChange( - final PropertyChangeEvent evt) { - propertySupport.firePropertyChange(evt); - } - - /** - * Fire property change event to appropriate listeners. - * @param propertyName property name. - * @param oldValue old value. - * @param newValue new value. - */ - protected final void firePropertyChange( - final String propertyName, - final boolean oldValue, - final boolean newValue) { - propertySupport.firePropertyChange(propertyName, oldValue, newValue); - } - - /** - * Fire property change event to appropriate listeners. - * @param propertyName property name. - * @param oldValue old value. - * @param newValue new value. - */ - protected final void firePropertyChange( - final String propertyName, - final int oldValue, final int newValue) { - propertySupport.firePropertyChange(propertyName, oldValue, newValue); - } - - /** - * Fire property change event to appropriate listeners. - * @param propertyName property name. - * @param oldValue old value. - * @param newValue new value. - */ - protected final void firePropertyChange( - final String propertyName, - final Object oldValue, - final Object newValue) { - propertySupport.firePropertyChange(propertyName, oldValue, newValue); - } -} diff --git a/src/main/java/org/apache/log4j/plugins/Receiver.java b/src/main/java/org/apache/log4j/plugins/Receiver.java deleted file mode 100644 index 4215b1a9c6..0000000000 --- a/src/main/java/org/apache/log4j/plugins/Receiver.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.plugins; - -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.Thresholdable; - - -/** - * Defines the base class for Receiver plugins. - *

    - *

    Just as Appenders send logging events outside of the log4j - * environment (to files, to smtp, to sockets, etc), Receivers bring - * logging events inside the log4j environment. - *

    - *

    Receivers are meant to support the receiving of - * remote logging events from another process. For example, - * SocketAppender "appends" a logging event to a socket, configured - * for a specific host and port number. On the receiving side of - * the socket can be a SocketReceiver object. The SocketReceiver - * object receives the logging event, and then "posts" it to the - * log4j environment (LoggerRepository) on the receiving machine, to - * be handled by the configured appenders, etc. The various - * settings in this environment (Logger levels, Appender filters & - * thresholds) are applied to the received logging event. - *

    - *

    Receivers can also be used to "import" log messages from other - * logging packages into the log4j environment. - *

    - *

    Receivers can be configured to post events to a given - * LoggerRepository. - *

    - *

    Subclasses of Receiver must implement the isActive(), - * activateOptions(), and shutdown() methods. The doPost() method - * is provided to standardize the "import" of remote events into - * the repository. - * - * @author Mark Womack - * @author Ceki Gülcü - * @author Paul Smith (psmith@apache.org) - * @since 1.3 - */ -public abstract class Receiver extends PluginSkeleton implements Thresholdable { - /** - * Threshold level. - */ - protected Level thresholdLevel; - - /** - * Create new instance. - */ - protected Receiver() { - super(); - } - - /** - * Sets the receiver theshold to the given level. - * - * @param level The threshold level events must equal or be greater - * than before further processing can be done. - */ - public void setThreshold(final Level level) { - Level oldValue = this.thresholdLevel; - thresholdLevel = level; - firePropertyChange("threshold", oldValue, this.thresholdLevel); - } - - /** - * Gets the current threshold setting of the receiver. - * - * @return Level The current threshold level of the receiver. - */ - public Level getThreshold() { - return thresholdLevel; - } - - /** - * Returns true if the given level is equals or greater than the current - * threshold value of the receiver. - * - * @param level The level to test against the receiver threshold. - * @return boolean True if level is equal or greater than the - * receiver threshold. - */ - public boolean isAsSevereAsThreshold(final Level level) { - return ((thresholdLevel == null) - || level.isGreaterOrEqual(thresholdLevel)); - } - - /** - * Posts the logging event to a logger in the configured logger - * repository. - * - * @param event the log event to post to the local log4j environment. - */ - public void doPost(final LoggingEvent event) { - // if event does not meet threshold, exit now - if (!isAsSevereAsThreshold(event.getLevel())) { - return; - } - - // get the "local" logger for this event from the - // configured repository. - Logger localLogger = - getLoggerRepository().getLogger(event.getLoggerName()); - - // if the logger level is greater or equal to the level - // of the event, use the logger to append the event. - if (event.getLevel() - .isGreaterOrEqual(localLogger.getEffectiveLevel())) { - // call the loggers appenders to process the event - localLogger.callAppenders(event); - } - } -} diff --git a/src/main/java/org/apache/log4j/rewrite/MapRewritePolicy.java b/src/main/java/org/apache/log4j/rewrite/MapRewritePolicy.java new file mode 100644 index 0000000000..4fca465373 --- /dev/null +++ b/src/main/java/org/apache/log4j/rewrite/MapRewritePolicy.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.rewrite; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.apache.log4j.spi.LoggingEvent; + +/** + * This policy rewrites events where the message of the + * original event implementes java.util.Map. + * All other events are passed through unmodified. + * If the map contains a "message" entry, the value will be + * used as the message for the rewritten event. The rewritten + * event will have a property set that is the combination of the + * original property set and the other members of the message map. + * If both the original property set and the message map + * contain the same entry, the value from the message map + * will overwrite the original property set. + * + * The combination of the RewriteAppender and this policy + * performs the same actions as the MapFilter from log4j 1.3. + */ +public class MapRewritePolicy implements RewritePolicy { + /** + * {@inheritDoc} + */ + public LoggingEvent rewrite(final LoggingEvent source) { + Object msg = source.getMessage(); + if (msg instanceof Map) { + Map props = new HashMap(source.getProperties()); + Map eventProps = (Map) msg; + // + // if the map sent in the logging request + // has "message" entry, use that as the message body + // otherwise, use the entire map. + // + Object newMsg = eventProps.get("message"); + if (newMsg == null) { + newMsg = msg; + } + + for(Iterator iter = eventProps.entrySet().iterator(); + iter.hasNext(); + ) { + Map.Entry entry = (Map.Entry) iter.next(); + if (!("message".equals(entry.getKey()))) { + props.put(entry.getKey(), entry.getValue()); + } + } + + return new LoggingEvent( + source.getFQNOfLoggerClass(), + source.getLogger() != null ? source.getLogger(): Logger.getLogger(source.getLoggerName()), + source.getTimeStamp(), + source.getLevel(), + newMsg, + source.getThreadName(), + source.getThrowableInformation(), + source.getNDC(), + source.getLocationInformation(), + props); + } else { + return source; + } + + } +} diff --git a/src/main/java/org/apache/log4j/rewrite/PropertyRewritePolicy.java b/src/main/java/org/apache/log4j/rewrite/PropertyRewritePolicy.java new file mode 100644 index 0000000000..535736c327 --- /dev/null +++ b/src/main/java/org/apache/log4j/rewrite/PropertyRewritePolicy.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.rewrite; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.StringTokenizer; + +import org.apache.log4j.Logger; +import org.apache.log4j.spi.LoggingEvent; + +/** + * This policy rewrites events by adding + * a user-specified list of properties to the event. + * Existing properties are not modified. + * + * The combination of the RewriteAppender and this policy + * performs the same actions as the PropertyFilter from log4j 1.3. + */ + +public class PropertyRewritePolicy implements RewritePolicy { + private Map properties = Collections.EMPTY_MAP; + public PropertyRewritePolicy() { + } + + /** + * Set a string representing the property name/value pairs. + * + * Form: propname1=propvalue1,propname2=propvalue2 + * + * @param props + */ + public void setProperties(String props) { + Map hashTable = new HashMap(); + StringTokenizer pairs = new StringTokenizer(props, ","); + while (pairs.hasMoreTokens()) { + StringTokenizer entry = new StringTokenizer(pairs.nextToken(), "="); + hashTable.put(entry.nextElement().toString().trim(), entry.nextElement().toString().trim()); + } + synchronized(this) { + properties = hashTable; + } + } + + /** + * {@inheritDoc} + */ + public LoggingEvent rewrite(final LoggingEvent source) { + if (!properties.isEmpty()) { + Map rewriteProps = new HashMap(source.getProperties()); + for(Iterator iter = properties.entrySet().iterator(); + iter.hasNext(); + ) { + Map.Entry entry = (Map.Entry) iter.next(); + if (!rewriteProps.containsKey(entry.getKey())) { + rewriteProps.put(entry.getKey(), entry.getValue()); + } + } + + return new LoggingEvent( + source.getFQNOfLoggerClass(), + source.getLogger() != null ? source.getLogger(): Logger.getLogger(source.getLoggerName()), + source.getTimeStamp(), + source.getLevel(), + source.getMessage(), + source.getThreadName(), + source.getThrowableInformation(), + source.getNDC(), + source.getLocationInformation(), + rewriteProps); + } + return source; + } + + + +} diff --git a/src/main/java/org/apache/log4j/rewrite/ReflectionRewritePolicy.java b/src/main/java/org/apache/log4j/rewrite/ReflectionRewritePolicy.java new file mode 100644 index 0000000000..f1a4cc55b1 --- /dev/null +++ b/src/main/java/org/apache/log4j/rewrite/ReflectionRewritePolicy.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.rewrite; + +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.util.HashMap; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.spi.LoggingEvent; + +/** + * This policy rewrites events by evaluating any + * JavaBean properties on the message object and adding them + * to the event properties. If the message object has a + * message property, the value of that property will be + * used as the message for the rewritten event and will + * not be added to the event properties. Values from the + * JavaBean properties will replace any existing property + * with the same name. + * + * The combination of the RewriteAppender and this policy + * performs the same actions as the ReflectionFilter from log4j 1.3. + */ +public class ReflectionRewritePolicy implements RewritePolicy { + /** + * {@inheritDoc} + */ + public LoggingEvent rewrite(final LoggingEvent source) { + Object msg = source.getMessage(); + if (!(msg instanceof String)) { + Object newMsg = msg; + Map rewriteProps = new HashMap(source.getProperties()); + + try { + PropertyDescriptor[] props = Introspector.getBeanInfo( + msg.getClass(), Object.class).getPropertyDescriptors(); + if (props.length > 0) { + for (int i=0;iAsyncAppender by interrupting the dispatcher + * thread which will process all pending events before exiting. + */ + public void close() { + closed = true; + // + // close all attached appenders. + // + synchronized (appenders) { + Enumeration iter = appenders.getAllAppenders(); + + if (iter != null) { + while (iter.hasMoreElements()) { + Object next = iter.nextElement(); + + if (next instanceof Appender) { + ((Appender) next).close(); + } + } + } + } + } + + /** + * Determines if specified appender is attached. + * @param appender appender. + * @return true if attached. + */ + public boolean isAttached(final Appender appender) { + synchronized (appenders) { + return appenders.isAttached(appender); + } + } + + /** + * {@inheritDoc} + */ + public boolean requiresLayout() { + return false; + } + + /** + * Removes and closes all attached appenders. + */ + public void removeAllAppenders() { + synchronized (appenders) { + appenders.removeAllAppenders(); + } + } + + /** + * Removes an appender. + * @param appender appender to remove. + */ + public void removeAppender(final Appender appender) { + synchronized (appenders) { + appenders.removeAppender(appender); + } + } + + /** + * Remove appender by name. + * @param name name. + */ + public void removeAppender(final String name) { + synchronized (appenders) { + appenders.removeAppender(name); + } + } + + + public void setRewritePolicy(final RewritePolicy rewritePolicy) { + policy = rewritePolicy; + } + /** + * {@inheritDoc} + */ + public boolean parseUnrecognizedElement(final Element element, + final Properties props) throws Exception { + final String nodeName = element.getNodeName(); + if ("rewritePolicy".equals(nodeName)) { + Object rewritePolicy = + org.apache.log4j.xml.DOMConfigurator.parseElement( + element, props, RewritePolicy.class); + if (rewritePolicy != null) { + if (rewritePolicy instanceof OptionHandler) { + ((OptionHandler) rewritePolicy).activateOptions(); + } + this.setRewritePolicy((RewritePolicy) rewritePolicy); + } + return true; + } + return false; + } + +} diff --git a/src/main/java/org/apache/log4j/rewrite/RewritePolicy.java b/src/main/java/org/apache/log4j/rewrite/RewritePolicy.java new file mode 100644 index 0000000000..bb40507440 --- /dev/null +++ b/src/main/java/org/apache/log4j/rewrite/RewritePolicy.java @@ -0,0 +1,37 @@ +package org.apache.log4j.rewrite; + +import org.apache.log4j.spi.LoggingEvent; + +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * This interface is implemented to provide a rewrite + * strategy for RewriteAppender. RewriteAppender will + * call the rewrite method with a source logging event. + * The strategy may return that event, create a new event + * or return null to suppress the logging request. + */ +public interface RewritePolicy { + /** + * Rewrite a logging event. + * @param source a logging event that may be returned or + * used to create a new logging event. + * @return a logging event or null to suppress processing. + */ + LoggingEvent rewrite(final LoggingEvent source); +} diff --git a/src/main/java/org/apache/log4j/rolling/FilterBasedTriggeringPolicy.java b/src/main/java/org/apache/log4j/rolling/FilterBasedTriggeringPolicy.java deleted file mode 100644 index a3106b8319..0000000000 --- a/src/main/java/org/apache/log4j/rolling/FilterBasedTriggeringPolicy.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling; - -import org.apache.log4j.Appender; -import org.apache.log4j.spi.Filter; -import org.apache.log4j.spi.LoggingEvent; - - -/** - * FilterBasedTriggeringPolicy determines if rolling should be triggered - * by evaluating the current message against a set of filters. Unless a - * filter rejects a message, a rolling event will be triggered. - * - * @author Curt Arnold - * @since 1.3 - * - */ -public final class FilterBasedTriggeringPolicy implements TriggeringPolicy { - /** - * The first filter in the filter chain. Set to null initially. - */ - private Filter headFilter; - - /** - * The last filter in the filter chain. - */ - private Filter tailFilter; - - /** - * Creates a new FilterBasedTriggeringPolicy. - */ - public FilterBasedTriggeringPolicy() { - } - - /** - * {@inheritDoc} - * - */ - public boolean isTriggeringEvent( - final Appender appender, final LoggingEvent event, final String file, - final long fileLength) { - // - // in the abnormal case of no contained filters - // always return true to avoid each logging event - // from having its own file. - if (headFilter == null) { - return false; - } - - // - // otherwise loop through the filters - // - for (Filter f = headFilter; f != null; f = f.getNext()) { - switch (f.decide(event)) { - case Filter.DENY: - return false; - - case Filter.ACCEPT: - return true; - } - } - - return true; - } - - /** - * Add a filter to end of the filter list. - * @param newFilter filter to add to end of list. - */ - public void addFilter(final Filter newFilter) { - if (headFilter == null) { - headFilter = newFilter; - tailFilter = newFilter; - } else { - tailFilter.setNext(newFilter); - tailFilter = newFilter; - } - } - - /** - * Clear the filters chain. - * - */ - public void clearFilters() { - headFilter = null; - tailFilter = null; - } - - /** - * Returns the head Filter. - * @return head of filter chain, may be null. - * - */ - public Filter getFilter() { - return headFilter; - } - - /** - * {@inheritDoc} - */ - public void activateOptions() { - for (Filter f = headFilter; f != null; f = f.getNext()) { - f.activateOptions(); - } - } -} diff --git a/src/main/java/org/apache/log4j/rolling/FixedWindowRollingPolicy.java b/src/main/java/org/apache/log4j/rolling/FixedWindowRollingPolicy.java deleted file mode 100644 index afd82a65bd..0000000000 --- a/src/main/java/org/apache/log4j/rolling/FixedWindowRollingPolicy.java +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import org.apache.log4j.pattern.PatternConverter; -import org.apache.log4j.rolling.helper.Action; -import org.apache.log4j.rolling.helper.FileRenameAction; -import org.apache.log4j.rolling.helper.GZCompressAction; -import org.apache.log4j.rolling.helper.ZipCompressAction; - - -/** - * When rolling over, FixedWindowRollingPolicy renames files - * according to a fixed window algorithm as described below. - * - *

    The ActiveFileName property, which is required, represents the name - * of the file where current logging output will be written. - * The FileNamePattern option represents the file name pattern for the - * archived (rolled over) log files. If present, the FileNamePattern - * option must include an integer token, that is the string "%i" somewhere - * within the pattern. - * - *

    Let max and min represent the values of respectively - * the MaxIndex and MinIndex options. Let "foo.log" be the value - * of the ActiveFile option and "foo.%i.log" the value of - * FileNamePattern. Then, when rolling over, the file - * foo.max.log will be deleted, the file - * foo.max-1.log will be renamed as - * foo.max.log, the file foo.max-2.log - * renamed as foo.max-1.log, and so on, - * the file foo.min+1.log renamed as - * foo.min+2.log. Lastly, the active file foo.log - * will be renamed as foo.min.log and a new active file name - * foo.log will be created. - * - *

    Given that this rollover algorithm requires as many file renaming - * operations as the window size, large window sizes are discouraged. The - * current implementation will automatically reduce the window size to 12 when - * larger values are specified by the user. - * - * - * @author Ceki Gülcü - * @since 1.3 - * */ -public final class FixedWindowRollingPolicy extends RollingPolicyBase { - - /** - * It's almost always a bad idea to have a large window size, say over 12. - */ - private static final int MAX_WINDOW_SIZE = 12; - - /** - * Index for oldest retained log file. - */ - private int maxIndex; - - /** - * Index for most recent log file. - */ - private int minIndex; - - /** - * if true, then an explicit name for the active file was - * specified using RollingFileAppender.file or the - * redundent RollingPolicyBase.setActiveFile - */ - private boolean explicitActiveFile; - - /** - * Constructs a new instance. - */ - public FixedWindowRollingPolicy() { - minIndex = 1; - maxIndex = 7; - } - - /** - * {@inheritDoc} - */ - public void activateOptions() { - super.activateOptions(); - - if (maxIndex < minIndex) { - getLogger().warn( - "MaxIndex (" + maxIndex + ") cannot be smaller than MinIndex (" - + minIndex + ")."); - getLogger().warn("Setting maxIndex to equal minIndex."); - maxIndex = minIndex; - } - - if ((maxIndex - minIndex) > MAX_WINDOW_SIZE) { - getLogger().warn("Large window sizes are not allowed."); - maxIndex = minIndex + MAX_WINDOW_SIZE; - getLogger().warn("MaxIndex reduced to {}.", new Integer(maxIndex)); - } - - PatternConverter itc = getIntegerPatternConverter(); - - if (itc == null) { - throw new IllegalStateException( - "FileNamePattern [" + getFileNamePattern() - + "] does not contain a valid integer format specifier"); - } - } - - /** - * {@inheritDoc} - */ - public RolloverDescription initialize( - final String file, final boolean append) { - String newActiveFile = file; - explicitActiveFile = false; - - if (activeFileName != null) { - explicitActiveFile = true; - newActiveFile = activeFileName; - } - - if (file != null) { - explicitActiveFile = true; - newActiveFile = file; - } - - if (!explicitActiveFile) { - StringBuffer buf = new StringBuffer(); - formatFileName(new Integer(minIndex), buf); - newActiveFile = buf.toString(); - } - - return new RolloverDescriptionImpl(newActiveFile, append, null, null); - } - - /** - * {@inheritDoc} - */ - public RolloverDescription rollover(final String currentFileName) { - if (maxIndex >= 0) { - int purgeStart = minIndex; - - if (!explicitActiveFile) { - purgeStart++; - } - - if (!purge(purgeStart, maxIndex)) { - return null; - } - - StringBuffer buf = new StringBuffer(); - formatFileName(new Integer(purgeStart), buf); - - String renameTo = buf.toString(); - String compressedName = renameTo; - Action compressAction = null; - - if (renameTo.endsWith(".gz")) { - renameTo = renameTo.substring(0, renameTo.length() - 3); - compressAction = - new GZCompressAction( - new File(renameTo), new File(compressedName), true, getLogger()); - } else if (renameTo.endsWith(".zip")) { - renameTo = renameTo.substring(0, renameTo.length() - 4); - compressAction = - new ZipCompressAction( - new File(renameTo), new File(compressedName), true, getLogger()); - } - - FileRenameAction renameAction = - new FileRenameAction( - new File(currentFileName), new File(renameTo), false); - - return new RolloverDescriptionImpl( - currentFileName, false, renameAction, compressAction); - } - - return null; - } - - /** - * Get index of oldest log file to be retained. - * @return index of oldest log file. - */ - public int getMaxIndex() { - return maxIndex; - } - - /** - * Get index of most recent log file. - * @return index of oldest log file. - */ - public int getMinIndex() { - return minIndex; - } - - /** - * Set index of oldest log file to be retained. - * @param maxIndex index of oldest log file to be retained. - */ - public void setMaxIndex(int maxIndex) { - this.maxIndex = maxIndex; - } - - /** - * Set index of most recent log file. - * @param minIndex Index of most recent log file. - */ - public void setMinIndex(int minIndex) { - this.minIndex = minIndex; - } - - /** - * Purge and rename old log files in preparation for rollover - * @param lowIndex low index - * @param highIndex high index. Log file associated with high - * index will be deleted if needed. - * @return true if purge was successful and rollover should be attempted. - */ - private boolean purge(final int lowIndex, final int highIndex) { - int suffixLength = 0; - - List renames = new ArrayList(); - StringBuffer buf = new StringBuffer(); - formatFileName(new Integer(lowIndex), buf); - - String lowFilename = buf.toString(); - - if (lowFilename.endsWith(".gz")) { - suffixLength = 3; - } else if (lowFilename.endsWith(".zip")) { - suffixLength = 4; - } - - for (int i = lowIndex; i <= highIndex; i++) { - File toRename = new File(lowFilename); - boolean isBase = false; - - if (suffixLength > 0) { - File toRenameBase = - new File( - lowFilename.substring(0, lowFilename.length() - suffixLength)); - - if (toRename.exists()) { - if (toRenameBase.exists()) { - toRenameBase.delete(); - } - } else { - toRename = toRenameBase; - isBase = true; - } - } - - if (toRename.exists()) { - // - // if at upper index then - // attempt to delete last file - // if that fails then abandon purge - if (i == highIndex) { - if (!toRename.delete()) { - return false; - } - - break; - } - - // - // if intermediate index - // add a rename action to the list - buf.setLength(0); - formatFileName(new Integer(i + 1), buf); - - String highFilename = buf.toString(); - String renameTo = highFilename; - - if (isBase) { - renameTo = - highFilename.substring(0, highFilename.length() - suffixLength); - } - - renames.add(new FileRenameAction(toRename, new File(renameTo), true)); - lowFilename = highFilename; - } else { - break; - } - } - - // - // work renames backwards - // - for (int i = renames.size() - 1; i >= 0; i--) { - Action action = (Action) renames.get(i); - - try { - if (!action.execute()) { - return false; - } - } catch (Exception ex) { - getLogger().info("Exception during purge in RollingFileAppender", ex); - - return false; - } - } - - return true; - } -} diff --git a/src/main/java/org/apache/log4j/rolling/RollingFileAppender.java b/src/main/java/org/apache/log4j/rolling/RollingFileAppender.java deleted file mode 100644 index 19a0d73573..0000000000 --- a/src/main/java/org/apache/log4j/rolling/RollingFileAppender.java +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling; - -import org.apache.log4j.FileAppender; -import org.apache.log4j.rolling.helper.Action; -import org.apache.log4j.spi.LoggingEvent; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; - - -/** - * RollingFileAppender extends {@link FileAppender} to backup the log files - * depending on {@link RollingPolicy} and {@link TriggeringPolicy}. - *

    - * To be of any use, a RollingFileAppender instance must have both - * a RollingPolicy and a TriggeringPolicy set up. - * However, if its RollingPolicy also implements the - * TriggeringPolicy interface, then only the former needs to be - * set up. For example, {@link TimeBasedRollingPolicy} acts both as a - * RollingPolicy and a TriggeringPolicy. - * - *

    RollingFileAppender can be configured programattically or - * using {@link org.apache.log4j.joran.JoranConfigurator}. Here is a sample - * configration file: - -

    <?xml version="1.0" encoding="UTF-8" ?>
    -<!DOCTYPE log4j:configuration>
    -
    -<log4j:configuration debug="true">
    -
    -  <appender name="ROLL" class="org.apache.log4j.rolling.RollingFileAppender">
    -    <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
    -      <param name="FileNamePattern" value="/wombat/foo.%d{yyyy-MM}.gz"/>
    -    </rollingPolicy>
    -
    -    <layout class="org.apache.log4j.PatternLayout">
    -      <param name="ConversionPattern" value="%c{1} - %m%n"/>
    -    </layout>
    -  </appender>
    -
    -  <root">
    -    <appender-ref ref="ROLL"/>
    -  </root>
    -
    -</log4j:configuration>
    -
    - - *

    This configuration file specifies a monthly rollover schedule including - * automatic compression of the archived files. See - * {@link TimeBasedRollingPolicy} for more details. - * - * @author Heinz Richter - * @author Ceki Gülcü - * @since 1.3 - * */ -public final class RollingFileAppender extends FileAppender { - /** - * Triggering policy. - */ - private TriggeringPolicy triggeringPolicy; - - /** - * Rolling policy. - */ - private RollingPolicy rollingPolicy; - - /** - * Length of current active log file. - */ - private long fileLength = 0; - - /** - * Asynchronous action (like compression) from previous rollover. - */ - private Action lastRolloverAsyncAction = null; - - /** - * Construct a new instance. - */ - public RollingFileAppender() { - } - - /** - * Prepare instance of use. - */ - public void activateOptions() { - if (rollingPolicy == null) { - getLogger().warn( - "Please set a rolling policy for the RollingFileAppender named '{}'", - getName()); - - return; - } - - // - // if no explicit triggering policy and rolling policy is both. - // - if ( - (triggeringPolicy == null) && rollingPolicy instanceof TriggeringPolicy) { - triggeringPolicy = (TriggeringPolicy) rollingPolicy; - } - - if (triggeringPolicy == null) { - getLogger().warn( - "Please set a TriggeringPolicy for the RollingFileAppender named '{}'", - getName()); - - return; - } - - Exception exception = null; - - synchronized (this) { - triggeringPolicy.activateOptions(); - rollingPolicy.activateOptions(); - - try { - RolloverDescription rollover = - rollingPolicy.initialize(getFile(), getAppend()); - - if (rollover != null) { - Action syncAction = rollover.getSynchronous(); - - if (syncAction != null) { - syncAction.execute(); - } - - setFile(rollover.getActiveFileName()); - setAppend(rollover.getAppend()); - lastRolloverAsyncAction = rollover.getAsynchronous(); - - if (lastRolloverAsyncAction != null) { - Thread runner = new Thread(lastRolloverAsyncAction); - runner.start(); - } - } - - File activeFile = new File(getFile()); - - if (getAppend()) { - fileLength = activeFile.length(); - } else { - fileLength = 0; - } - - super.activateOptions(); - } catch (Exception ex) { - exception = ex; - } - } - - if (exception != null) { - getLogger().warn( - "Exception while initializing RollingFileAppender named '" + getName() - + "'", exception); - } - } - - /** - Implements the usual roll over behaviour. - -

    If MaxBackupIndex is positive, then files - {File.1, ..., File.MaxBackupIndex -1} - are renamed to {File.2, ..., - File.MaxBackupIndex}. Moreover, File is - renamed File.1 and closed. A new File is - created to receive further log output. - -

    If MaxBackupIndex is equal to zero, then the - File is truncated with no backup files created. - - * @return true if rollover performed. - */ - public boolean rollover() { - // - // can't roll without a policy - // - if (rollingPolicy != null) { - Exception exception = null; - - synchronized (this) { - // - // if a previous async task is still running - //} - if (lastRolloverAsyncAction != null) { - // - // block until complete - // - lastRolloverAsyncAction.close(); - - // - // or don't block and return to rollover later - // - //if (!lastRolloverAsyncAction.isComplete()) return false; - } - - try { - RolloverDescription rollover = rollingPolicy.rollover(getFile()); - - if (rollover != null) { - if (rollover.getActiveFileName().equals(getFile())) { - closeWriter(); - - boolean success = true; - - if (rollover.getSynchronous() != null) { - success = false; - - try { - success = rollover.getSynchronous().execute(); - } catch (Exception ex) { - exception = ex; - } - } - - if (success) { - if (rollover.getAppend()) { - fileLength = new File(rollover.getActiveFileName()).length(); - } else { - fileLength = 0; - } - - if (rollover.getAsynchronous() != null) { - lastRolloverAsyncAction = rollover.getAsynchronous(); - new Thread(lastRolloverAsyncAction).start(); - } - - setFile( - rollover.getActiveFileName(), rollover.getAppend(), - bufferedIO, bufferSize); - } else { - setFile( - rollover.getActiveFileName(), true, bufferedIO, bufferSize); - - if (exception == null) { - getLogger().warn("Failure in post-close rollover action"); - } else { - getLogger().warn( - "Exception in post-close rollover action", exception); - } - } - } else { - Writer newWriter = - createWriter( - new FileOutputStream( - rollover.getActiveFileName(), rollover.getAppend())); - closeWriter(); - setFile(rollover.getActiveFileName()); - this.qw = createQuietWriter(newWriter); - - boolean success = true; - - if (rollover.getSynchronous() != null) { - success = false; - - try { - success = rollover.getSynchronous().execute(); - } catch (Exception ex) { - exception = ex; - } - } - - if (success) { - if (rollover.getAppend()) { - fileLength = new File(rollover.getActiveFileName()).length(); - } else { - fileLength = 0; - } - - if (rollover.getAsynchronous() != null) { - lastRolloverAsyncAction = rollover.getAsynchronous(); - new Thread(lastRolloverAsyncAction).start(); - } - } - - writeHeader(); - } - - return true; - } - } catch (Exception ex) { - exception = ex; - } - } - - if (exception != null) { - getLogger().warn( - "Exception during rollover, rollover deferred.", exception); - } - } - - return false; - } - - /** - * {@inheritDoc} - */ - protected void subAppend(final LoggingEvent event) { - // The rollover check must precede actual writing. This is the - // only correct behavior for time driven triggers. - if ( - triggeringPolicy.isTriggeringEvent( - this, event, getFile(), getFileLength())) { - // - // wrap rollover request in try block since - // rollover may fail in case read access to directory - // is not provided. However appender should still be in good - // condition and the append should still happen. - try { - rollover(); - } catch (Exception ex) { - getLogger().info("Exception during rollover attempt.", ex); - } - } - - super.subAppend(event); - } - - /** - * Get rolling policy. - * @return rolling policy. - */ - public RollingPolicy getRollingPolicy() { - return rollingPolicy; - } - - /** - * Get triggering policy. - * @return triggering policy. - */ - public TriggeringPolicy getTriggeringPolicy() { - return triggeringPolicy; - } - - /** - * Sets the rolling policy. - * @param policy rolling policy. - */ - public void setRollingPolicy(final RollingPolicy policy) { - rollingPolicy = policy; - } - - /** - * Set triggering policy. - * @param policy triggering policy. - */ - public void setTriggeringPolicy(final TriggeringPolicy policy) { - triggeringPolicy = policy; - } - - /** - * Close appender. Waits for any asynchronous file compression actions to be completed. - */ - public void close() { - synchronized (this) { - if (lastRolloverAsyncAction != null) { - lastRolloverAsyncAction.close(); - } - } - - super.close(); - } - - /** - Returns an OutputStreamWriter when passed an OutputStream. The - encoding used will depend on the value of the - encoding property. If the encoding value is - specified incorrectly the writer will be opened using the default - system encoding (an error message will be printed to the loglog. - @param os output stream, may not be null. - @return new writer. - */ - protected OutputStreamWriter createWriter(final OutputStream os) { - return super.createWriter(new CountingOutputStream(os, this)); - } - - /** - * Get byte length of current active log file. - * @return byte length of current active log file. - */ - public long getFileLength() { - return fileLength; - } - - /** - * Increments estimated byte length of current active log file. - * @param increment additional bytes written to log file. - */ - public synchronized void incrementFileLength(int increment) { - fileLength += increment; - } - - /** - * Wrapper for OutputStream that will report all write - * operations back to this class for file length calculations. - */ - private static class CountingOutputStream extends OutputStream { - /** - * Wrapped output stream. - */ - private final OutputStream os; - - /** - * Rolling file appender to inform of stream writes. - */ - private final RollingFileAppender rfa; - - /** - * Constructor. - * @param os output stream to wrap. - * @param rfa rolling file appender to inform. - */ - public CountingOutputStream( - final OutputStream os, final RollingFileAppender rfa) { - this.os = os; - this.rfa = rfa; - } - - /** - * {@inheritDoc} - */ - public void close() throws IOException { - os.close(); - } - - /** - * {@inheritDoc} - */ - public void flush() throws IOException { - os.flush(); - } - - /** - * {@inheritDoc} - */ - public void write(final byte[] b) throws IOException { - os.write(b); - rfa.incrementFileLength(b.length); - } - - /** - * {@inheritDoc} - */ - public void write(final byte[] b, final int off, final int len) - throws IOException { - os.write(b, off, len); - rfa.incrementFileLength(len); - } - - /** - * {@inheritDoc} - */ - public void write(final int b) throws IOException { - os.write(b); - rfa.incrementFileLength(1); - } - } -} diff --git a/src/main/java/org/apache/log4j/rolling/RollingPolicy.java b/src/main/java/org/apache/log4j/rolling/RollingPolicy.java deleted file mode 100644 index 31da9b2fe3..0000000000 --- a/src/main/java/org/apache/log4j/rolling/RollingPolicy.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling; - -import org.apache.log4j.spi.OptionHandler; - - -/** - * A RollingPolicy specifies the actions taken - * on a logging file rollover. - * - * @author Ceki Gülcü - * @author Curt Arnold - * @since 1.3 - * */ -public interface RollingPolicy extends OptionHandler { - /** - * Initialize the policy and return any initial actions for rolling file appender.. - * - * @param file current value of RollingFileAppender.getFile(). - * @param append current value of RollingFileAppender.getAppend(). - * @return Description of the initialization, may be null to indicate - * no initialization needed. - * @throws SecurityException if denied access to log files. - */ - public RolloverDescription initialize( - final String file, final boolean append) throws SecurityException; - - /** - * Prepare for a rollover. This method is called prior to - * closing the active log file, performs any necessary - * preliminary actions and describes actions needed - * after close of current log file. - * - * @param activeFile file name for current active log file. - * @return Description of pending rollover, may be null to indicate no rollover - * at this time. - * @throws SecurityException if denied access to log files. - */ - public RolloverDescription rollover(final String activeFile) throws SecurityException; -} diff --git a/src/main/java/org/apache/log4j/rolling/RollingPolicyBase.java b/src/main/java/org/apache/log4j/rolling/RollingPolicyBase.java deleted file mode 100644 index 3615ff1c84..0000000000 --- a/src/main/java/org/apache/log4j/rolling/RollingPolicyBase.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling; - -import org.apache.log4j.pattern.FormattingInfo; -import org.apache.log4j.pattern.PatternConverter; -import org.apache.log4j.pattern.PatternParser; -import org.apache.log4j.pattern.IntegerPatternConverter; -import org.apache.log4j.pattern.DatePatternConverter; -import org.apache.log4j.spi.ComponentBase; -import org.apache.log4j.spi.OptionHandler; - -import java.util.ArrayList; -import java.util.List; - - -/** - * Implements methods common to most, it not all, rolling - * policies. Currently such methods are limited to a compression mode - * getter/setter. - * - * @author Ceki Gülcü - * @author Curt Arnold - * @since 1.3 - */ -public abstract class RollingPolicyBase extends ComponentBase - implements RollingPolicy, OptionHandler { - /** - * Error message. - */ - private static final String FNP_NOT_SET = - "The FileNamePattern option must be set before using RollingPolicy. "; - - /** - * Reference for error message. - */ - private static final String SEE_FNP_NOT_SET = - "See also http://logging.apache.org/log4j/codes.html#tbr_fnp_not_set"; - - /** - * File name pattern converters. - */ - private PatternConverter[] patternConverters; - - /** - * File name field specifiers. - */ - private FormattingInfo[] patternFields; - - /** - * File name pattern. - */ - private String fileNamePatternStr; - - /** - * Active file name may be null. - * Duplicates FileAppender.file and should be removed. - */ - protected String activeFileName; - - /** - * {@inheritDoc} - */ - public void activateOptions() { - // find out period from the filename pattern - if (fileNamePatternStr != null) { - parseFileNamePattern(); - } else { - getLogger().warn(FNP_NOT_SET); - getLogger().warn(SEE_FNP_NOT_SET); - throw new IllegalStateException(FNP_NOT_SET + SEE_FNP_NOT_SET); - } - - } - - /** - * Set file name pattern. - * @param fnp file name pattern. - */ - public void setFileNamePattern(String fnp) { - fileNamePatternStr = fnp; - } - - /** - * Get file name pattern. - * @return file name pattern. - */ - public String getFileNamePattern() { - return fileNamePatternStr; - } - - /** - * ActiveFileName can be left unset, i.e. as null. - * @param afn active file name. - * @deprecated Duplicates FileAppender.file and should be removed - */ - public void setActiveFileName(String afn) { - activeFileName = afn; - } - - /** - * Return the value of the ActiveFile option. - * @deprecated Duplicates FileAppender.file and should be removed - * @return active file name. - */ - public String getActiveFileName() { - return activeFileName; - } - - /** - * Parse file name pattern. - */ - protected final void parseFileNamePattern() { - List converters = new ArrayList(); - List fields = new ArrayList(); - - PatternParser.parse( - fileNamePatternStr, converters, fields, null, - PatternParser.getFileNamePatternRules(), getLogger()); - patternConverters = new PatternConverter[converters.size()]; - patternConverters = - (PatternConverter[]) converters.toArray(patternConverters); - patternFields = new FormattingInfo[converters.size()]; - patternFields = (FormattingInfo[]) fields.toArray(patternFields); - } - - /** - * Format file name. - * - * @param obj object to be evaluted in formatting, may not be null. - * @param buf string buffer to which formatted file name is appended, may not be null. - */ - protected final void formatFileName( - final Object obj, final StringBuffer buf) { - for (int i = 0; i < patternConverters.length; i++) { - int fieldStart = buf.length(); - patternConverters[i].format(obj, buf); - - if (patternFields[i] != null) { - patternFields[i].format(fieldStart, buf); - } - } - } - - protected final PatternConverter getDatePatternConverter() { - for (int i = 0; i < patternConverters.length; i++) { - if (patternConverters[i] instanceof DatePatternConverter) { - return patternConverters[i]; - } - } - return null; - - } - - protected final PatternConverter getIntegerPatternConverter() { - for (int i = 0; i < patternConverters.length; i++) { - if (patternConverters[i] instanceof IntegerPatternConverter) { - return patternConverters[i]; - } - } - return null; - } - -} diff --git a/src/main/java/org/apache/log4j/rolling/RolloverDescription.java b/src/main/java/org/apache/log4j/rolling/RolloverDescription.java deleted file mode 100644 index cb7631d759..0000000000 --- a/src/main/java/org/apache/log4j/rolling/RolloverDescription.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling; - -import org.apache.log4j.rolling.helper.Action; - - -/** - * Description of actions needed to complete rollover. - * - * @author Curt Arnold - * @since 1.3 - * - */ -public interface RolloverDescription { - /** - * Active log file name after rollover. - * @return active log file name after rollover. - */ - String getActiveFileName(); - - /** - * Specifies if active file should be opened for appending. - * @return if true, active file should be opened for appending. - */ - boolean getAppend(); - - /** - * Action to be completed after close of current active log file - * before returning control to caller. - * - * @return action, may be null. - */ - Action getSynchronous(); - - /** - * Action to be completed after close of current active log file - * and before next rollover attempt, may be executed asynchronously. - * - * @return action, may be null. - */ - Action getAsynchronous(); -} diff --git a/src/main/java/org/apache/log4j/rolling/RolloverDescriptionImpl.java b/src/main/java/org/apache/log4j/rolling/RolloverDescriptionImpl.java deleted file mode 100644 index 05cb0d24c0..0000000000 --- a/src/main/java/org/apache/log4j/rolling/RolloverDescriptionImpl.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling; - -import org.apache.log4j.rolling.helper.Action; - - -/** - * Description of actions needed to complete rollover. - * - * @author Curt Arnold - * @since 1.3 - * - */ -public final class RolloverDescriptionImpl implements RolloverDescription { - /** - * Active log file name after rollover. - */ - private final String activeFileName; - - /** - * Should active file be opened for appending. - */ - private final boolean append; - - /** - * Action to be completed after close of current active log file - * before returning control to caller. - */ - private final Action synchronous; - - /** - * Action to be completed after close of current active log file - * and before next rollover attempt, may be executed asynchronously. - */ - private final Action asynchronous; - - /** - * Create new instance. - * @param activeFileName active log file name after rollover, may not be null. - * @param append true if active log file after rollover should be opened for appending. - * @param synchronous action to be completed after close of current active log file, may be null. - * @param asynchronous action to be completed after close of current active log file and - * before next rollover attempt. - */ - public RolloverDescriptionImpl( - final String activeFileName, final boolean append, final Action synchronous, - final Action asynchronous) { - if (activeFileName == null) { - throw new NullPointerException("activeFileName"); - } - - this.append = append; - this.activeFileName = activeFileName; - this.synchronous = synchronous; - this.asynchronous = asynchronous; - } - - /** - * Active log file name after rollover. - * @return active log file name after rollover. - */ - public String getActiveFileName() { - return activeFileName; - } - - /** - * {@inheritDoc} - */ - public boolean getAppend() { - return append; - } - - /** - * Action to be completed after close of current active log file - * before returning control to caller. - * - * @return action, may be null. - */ - public Action getSynchronous() { - return synchronous; - } - - /** - * Action to be completed after close of current active log file - * and before next rollover attempt, may be executed asynchronously. - * - * @return action, may be null. - */ - public Action getAsynchronous() { - return asynchronous; - } -} diff --git a/src/main/java/org/apache/log4j/rolling/SizeBasedTriggeringPolicy.java b/src/main/java/org/apache/log4j/rolling/SizeBasedTriggeringPolicy.java deleted file mode 100644 index d75d4741e7..0000000000 --- a/src/main/java/org/apache/log4j/rolling/SizeBasedTriggeringPolicy.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling; - -import org.apache.log4j.Appender; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.OptionHandler; - - -/** - * SizeBasedTriggeringPolicy looks at size of the file being - * currently written to. - * - * @author Ceki Gülcü - * @author Curt Arnold - * - */ -public final class SizeBasedTriggeringPolicy implements TriggeringPolicy, - OptionHandler { - /** - * Rollover threshold size in bytes. - */ - private long maxFileSize = 10 * 1024 * 1024; // let 10 MB the default max size - - /** - * Constructs a new instance. - */ - public SizeBasedTriggeringPolicy() { - } - - /** - * Constructs an new instance. - * @param maxFileSize rollover threshold size in bytes. - */ - public SizeBasedTriggeringPolicy(final long maxFileSize) { - this.maxFileSize = maxFileSize; - } - - /** - * {@inheritDoc} - */ - public boolean isTriggeringEvent( - final Appender appender, final LoggingEvent event, final String file, - final long fileLength) { - //System.out.println("Size"+file.length()); - return (fileLength >= maxFileSize); - } - - /** - * Gets rollover threshold size in bytes. - * @return rollover threshold size in bytes. - */ - public long getMaxFileSize() { - return maxFileSize; - } - - /** - * Sets rollover threshold size in bytes. - * @param l new value for rollover threshold size. - */ - public void setMaxFileSize(long l) { - maxFileSize = l; - } - - /** - * Prepares policy for use. - */ - public void activateOptions() { - } -} diff --git a/src/main/java/org/apache/log4j/rolling/TimeBasedRollingPolicy.java b/src/main/java/org/apache/log4j/rolling/TimeBasedRollingPolicy.java deleted file mode 100644 index 473b2dcfa2..0000000000 --- a/src/main/java/org/apache/log4j/rolling/TimeBasedRollingPolicy.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling; - -import java.io.File; -import java.util.Date; - -import org.apache.log4j.Appender; -import org.apache.log4j.pattern.PatternConverter; -import org.apache.log4j.rolling.helper.Action; -import org.apache.log4j.rolling.helper.FileRenameAction; -import org.apache.log4j.rolling.helper.GZCompressAction; -import org.apache.log4j.rolling.helper.ZipCompressAction; -import org.apache.log4j.spi.LoggingEvent; - - -/** - * TimeBasedRollingPolicy is both easy to configure and quite - * powerful. - * - *

    In order to use TimeBasedRollingPolicy, the - * FileNamePattern option must be set. It basically specifies the name of the - * rolled log files. The value FileNamePattern should consist of - * the name of the file, plus a suitably placed %d conversion - * specifier. The %d conversion specifier may contain a date and - * time pattern as specified by the {@link java.text.SimpleDateFormat} class. If - * the date and time pattern is ommitted, then the default pattern of - * "yyyy-MM-dd" is assumed. The following examples should clarify the point. - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    FileNamePattern valueRollover scheduleExample
    /wombat/folder/foo.%dDaily rollover (at midnight). Due to the omission of the optional - * time and date pattern for the %d token specifier, the default pattern - * of "yyyy-MM-dd" is assumed, which corresponds to daily rollover. - * During November 23rd, 2004, logging output will go to - * the file /wombat/foo.2004-11-23. At midnight and for - * the rest of the 24th, logging output will be directed to - * /wombat/foo.2004-11-24. - *
    /wombat/foo.%d{yyyy-MM}.logRollover at the beginning of each month.During the month of October 2004, logging output will go to - * /wombat/foo.2004-10.log. After midnight of October 31st - * and for the rest of November, logging output will be directed to - * /wombat/foo.2004-11.log. - *
    - *

    Automatic file compression

    - * TimeBasedRollingPolicy supports automatic file compression. - * This feature is enabled if the value of the FileNamePattern option - * ends with .gz or .zip. - *

    - * - * - * - * - * - * - * - * - * - * - * - *
    FileNamePattern valueRollover scheduleExample
    /wombat/foo.%d.gzDaily rollover (at midnight) with automatic GZIP compression of the - * archived files.During November 23rd, 2004, logging output will go to - * the file /wombat/foo.2004-11-23. However, at midnight that - * file will be compressed to become /wombat/foo.2004-11-23.gz. - * For the 24th of November, logging output will be directed to - * /wombat/folder/foo.2004-11-24 until its rolled over at the - * beginning of the next day. - *
    - * - *

    Decoupling the location of the active log file and the archived log files

    - *

    The active file is defined as the log file for the current period - * whereas archived files are those files which have been rolled over - * in previous periods. - * - *

    By setting the ActiveFileName option you can decouple the location - * of the active log file and the location of the archived log files. - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    FileNamePattern valueActiveFileNameRollover scheduleExample
    /wombat/foo.log.%d/wombat/foo.logDaily rollover.During November 23rd, 2004, logging output will go to - * the file /wombat/foo.log. However, at midnight that file - * will archived as /wombat/foo.log.2004-11-23. For the 24th - * of November, logging output will be directed to - * /wombat/folder/foo.log until its archived as - * /wombat/foo.log.2004-11-24 at the beginning of the next - * day. - *
    - *

    - * If configuring programatically, do not forget to call {@link #activateOptions} - * method before using this policy. Moreover, {@link #activateOptions} of - * TimeBasedRollingPolicy must be called before calling - * the {@link #activateOptions} method of the owning - * RollingFileAppender. - * - * @author Ceki Gülcü - * @author Curt Arnold - * @since 1.3 - */ -public final class TimeBasedRollingPolicy extends RollingPolicyBase - implements TriggeringPolicy { - - /** - * Time for next determination if time for rollover. - */ - private long nextCheck = 0; - - /** - * File name at last rollover. - */ - private String lastFileName = null; - - /** - * Length of any file type suffix (.gz, .zip). - */ - private int suffixLength = 0; - - /** - * Constructs a new instance. - */ - public TimeBasedRollingPolicy() { - } - - /** - * Prepares instance of use. - */ - public void activateOptions() { - super.activateOptions(); - - PatternConverter dtc = getDatePatternConverter(); - - if (dtc == null) { - throw new IllegalStateException( - "FileNamePattern [" + getFileNamePattern() - + "] does not contain a valid date format specifier"); - } - - long n = System.currentTimeMillis(); - StringBuffer buf = new StringBuffer(); - formatFileName(new Date(n), buf); - lastFileName = buf.toString(); - - suffixLength = 0; - - if (lastFileName.endsWith(".gz")) { - suffixLength = 3; - } else if (lastFileName.endsWith(".zip")) { - suffixLength = 4; - } - } - - /** - * {@inheritDoc} - */ - public RolloverDescription initialize( - final String currentActiveFile, final boolean append) { - long n = System.currentTimeMillis(); - nextCheck = ((n / 1000) + 1) * 1000; - - StringBuffer buf = new StringBuffer(); - formatFileName(new Date(n), buf); - lastFileName = buf.toString(); - - // - // RollingPolicyBase.activeFileName duplicates RollingFileAppender.file - // and should be removed. - // - if (activeFileName != null) { - return new RolloverDescriptionImpl(activeFileName, append, null, null); - } else if (currentActiveFile != null) { - return new RolloverDescriptionImpl( - currentActiveFile, append, null, null); - } else { - return new RolloverDescriptionImpl( - lastFileName.substring(0, lastFileName.length() - suffixLength), append, - null, null); - } - } - - /** - * {@inheritDoc} - */ - public RolloverDescription rollover(final String currentActiveFile) { - long n = System.currentTimeMillis(); - nextCheck = ((n / 1000) + 1) * 1000; - - StringBuffer buf = new StringBuffer(); - formatFileName(new Date(n), buf); - - String newFileName = buf.toString(); - - // - // if file names haven't changed, no rollover - // - if (newFileName.equals(lastFileName)) { - return null; - } - - Action renameAction = null; - Action compressAction = null; - String lastBaseName = - lastFileName.substring(0, lastFileName.length() - suffixLength); - String nextActiveFile = - newFileName.substring(0, newFileName.length() - suffixLength); - - // - // if currentActiveFile is not lastBaseName then - // active file name is not following file pattern - // and requires a rename plus maintaining the same name - if (!currentActiveFile.equals(lastBaseName)) { - renameAction = - new FileRenameAction( - new File(currentActiveFile), new File(lastBaseName), true); - nextActiveFile = currentActiveFile; - } - - if (suffixLength == 3) { - compressAction = - new GZCompressAction( - new File(lastBaseName), new File(lastFileName), true, getLogger()); - } - - if (suffixLength == 4) { - compressAction = - new ZipCompressAction( - new File(lastBaseName), new File(lastFileName), true, getLogger()); - } - - lastFileName = newFileName; - - return new RolloverDescriptionImpl( - nextActiveFile, false, renameAction, compressAction); - } - - /** - * {@inheritDoc} - */ - public boolean isTriggeringEvent( - final Appender appender, final LoggingEvent event, final String filename, - final long fileLength) { - return System.currentTimeMillis() >= nextCheck; - } -} diff --git a/src/main/java/org/apache/log4j/rolling/TriggeringPolicy.java b/src/main/java/org/apache/log4j/rolling/TriggeringPolicy.java deleted file mode 100644 index cd144940b3..0000000000 --- a/src/main/java/org/apache/log4j/rolling/TriggeringPolicy.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling; - -import org.apache.log4j.Appender; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.OptionHandler; - - -/** - * A TriggeringPolicy controls the conditions under which rollover - * occurs. Such conditions include time of day, file size, an - * external event, the log request or a combination thereof. - * - * @author Ceki Gülcü - * @author Curt Arnold - * @since 1.3 - * */ -public interface TriggeringPolicy extends OptionHandler { - /** - * Determines if a rollover may be appropriate at this time. If - * true is returned, RolloverPolicy.rollover will be called but it - * can determine that a rollover is not warranted. - * - * @param appender A reference to the appender. - * @param event A reference to the currently event. - * @param filename The filename for the currently active log file. - * @param fileLength Length of the file in bytes. - * @return true if a rollover should occur. - */ - public boolean isTriggeringEvent( - final Appender appender, final LoggingEvent event, final String filename, - final long fileLength); -} diff --git a/src/main/java/org/apache/log4j/rolling/helper/Action.java b/src/main/java/org/apache/log4j/rolling/helper/Action.java deleted file mode 100644 index 2901fa2b56..0000000000 --- a/src/main/java/org/apache/log4j/rolling/helper/Action.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling.helper; - -import java.io.IOException; - - -/** - * The Action interface should be implemented by any class that performs - * file system actions for RollingFileAppenders after the close of - * the active log file. - * - * @author Curt Arnold - * @since 1.3 - */ -public interface Action extends Runnable { - /** - * Perform an action. - * @return true if action was successful. A return value of false will cause - * the rollover to be aborted if possible. - * @throws IOException if IO error, a thrown exception will cause the rollover - * to be aborted if possible. - */ - boolean execute() throws IOException; - - /** - * Cancels the action if not already initialized or waits till completion. - */ - void close(); - - /** - * Determines if action has been completed. - * @return true if action is complete. - */ - boolean isComplete(); -} diff --git a/src/main/java/org/apache/log4j/rolling/helper/ActionBase.java b/src/main/java/org/apache/log4j/rolling/helper/ActionBase.java deleted file mode 100644 index 6ed44f4f41..0000000000 --- a/src/main/java/org/apache/log4j/rolling/helper/ActionBase.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling.helper; - -import java.io.IOException; - - -/** - * Abstract base class for implementations of Action. - * - * @author Curt Arnold - * @since 1.3 - */ -public abstract class ActionBase implements Action { - /** - * Is action complete. - */ - private boolean complete = false; - - /** - * Is action interrupted. - */ - private boolean interrupted = false; - - /** - * Constructor. - */ - protected ActionBase() { - } - - /** - * Perform action. - * - * @throws IOException if IO error. - * @return true if successful. - */ - public abstract boolean execute() throws IOException; - - /** - * {@inheritDoc} - */ - public synchronized void run() { - if (!interrupted) { - try { - execute(); - } catch (IOException ex) { - reportException(ex); - } - - complete = true; - interrupted = true; - } - } - - /** - * {@inheritDoc} - */ - public synchronized void close() { - interrupted = true; - } - - /** - * Tests if the action is complete. - * @return true if action is complete. - */ - public boolean isComplete() { - return complete; - } - - /** - * Capture exception. - * - * @param ex exception. - */ - protected void reportException(final Exception ex) { - } -} diff --git a/src/main/java/org/apache/log4j/rolling/helper/CompositeAction.java b/src/main/java/org/apache/log4j/rolling/helper/CompositeAction.java deleted file mode 100644 index b8e24ebd8b..0000000000 --- a/src/main/java/org/apache/log4j/rolling/helper/CompositeAction.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling.helper; - -import java.io.IOException; - -import java.util.List; -import org.apache.log4j.ULogger; - - -/** - * A group of Actions to be executed in sequence. - * - * @author Curt Arnold - * @since 1.3 - * - */ -public class CompositeAction extends ActionBase { - /** - * Actions to perform. - */ - private final Action[] actions; - - /** - * Stop on error. - */ - private final boolean stopOnError; - /** - * Logger. - */ - private final ULogger logger; - - /** - * Construct a new composite action. - * @param actions list of actions, may not be null. - * @param stopOnError if true, stop on the first false return value or exception. - * @param logger logger, may be null. - */ - public CompositeAction(final List actions, - final boolean stopOnError, - final ULogger logger) { - this.actions = new Action[actions.size()]; - actions.toArray(this.actions); - this.stopOnError = stopOnError; - this.logger = logger; - } - - /** - * {@inheritDoc} - */ - public void run() { - try { - execute(); - } catch (IOException ex) { - if (logger != null) { - logger.info("Exception during file rollover.", ex); - } - } - } - - /** - * Execute sequence of actions. - * @return true if all actions were successful. - * @throws IOException on IO error. - */ - public boolean execute() throws IOException { - if (stopOnError) { - for (int i = 0; i < actions.length; i++) { - if (!actions[i].execute()) { - return false; - } - } - - return true; - } else { - boolean status = true; - IOException exception = null; - - for (int i = 0; i < actions.length; i++) { - try { - status &= actions[i].execute(); - } catch (IOException ex) { - status = false; - - if (exception == null) { - exception = ex; - } - } - } - - if (exception != null) { - throw exception; - } - - return status; - } - } -} diff --git a/src/main/java/org/apache/log4j/rolling/helper/FileRenameAction.java b/src/main/java/org/apache/log4j/rolling/helper/FileRenameAction.java deleted file mode 100644 index 4388ab0fcb..0000000000 --- a/src/main/java/org/apache/log4j/rolling/helper/FileRenameAction.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling.helper; - -import java.io.File; - - -/** - * File rename action. - * - * @author Curt Arnold - * @since 1.3 - */ -public final class FileRenameAction extends ActionBase { - /** - * Source. - */ - private final File source; - - /** - * Destination. - */ - private final File destination; - - /** - * If true, rename empty files, otherwise delete empty files. - */ - private final boolean renameEmptyFiles; - - /** - * Creates an FileRenameAction. - * - * @param src current file name. - * @param dst new file name. - * @param renameEmptyFiles if true, rename file even if empty, otherwise delete empty files. - */ - public FileRenameAction( - final File src, final File dst, boolean renameEmptyFiles) { - source = src; - destination = dst; - this.renameEmptyFiles = renameEmptyFiles; - } - - /** - * Rename file. - * - * @return true if successfully renamed. - */ - public boolean execute() { - return execute(source, destination, renameEmptyFiles); - } - - /** - * Rename file. - * @param source current file name. - * @param destination new file name. - * @param renameEmptyFiles if true, rename file even if empty, otherwise delete empty files. - * @return true if successfully renamed. - */ - public static boolean execute( - final File source, final File destination, boolean renameEmptyFiles) { - if (renameEmptyFiles || (source.length() > 0)) { - return source.renameTo(destination); - } - - return source.delete(); - } -} diff --git a/src/main/java/org/apache/log4j/rolling/helper/GZCompressAction.java b/src/main/java/org/apache/log4j/rolling/helper/GZCompressAction.java deleted file mode 100644 index d5015c4c75..0000000000 --- a/src/main/java/org/apache/log4j/rolling/helper/GZCompressAction.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling.helper; - -import org.apache.log4j.ULogger; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; - -import java.util.zip.GZIPOutputStream; - - -/** - * Compresses a file using GZ compression. - * - * @author Curt Arnold - * @since 1.3 - */ -public final class GZCompressAction extends ActionBase { - /** - * Source file. - */ - private final File source; - - /** - * Destination file. - */ - private final File destination; - - /** - * If true, attempt to delete file on completion. - */ - private final boolean deleteSource; - - /** - * Logger to receive diagnostic messages. - */ - private final ULogger logger; - - /** - * Create new instance of GZCompressAction. - * - * @param source file to compress, may not be null. - * @param destination compressed file, may not be null. - * @param deleteSource if true, attempt to delete file on completion. Failure to delete - * does not cause an exception to be thrown or affect return value. - * @param logger logger, may be null. - */ - public GZCompressAction( - final File source, final File destination, final boolean deleteSource, - final ULogger logger) { - if (source == null) { - throw new NullPointerException("source"); - } - - if (destination == null) { - throw new NullPointerException("destination"); - } - - this.source = source; - this.destination = destination; - this.deleteSource = deleteSource; - this.logger = logger; - } - - /** - * Compress. - * @return true if successfully compressed. - * @throws IOException on IO exception. - */ - public boolean execute() throws IOException { - return execute(source, destination, deleteSource, logger); - } - - /** - * Compress a file. - * - * @param source file to compress, may not be null. - * @param destination compressed file, may not be null. - * @param deleteSource if true, attempt to delete file on completion. Failure to delete - * does not cause an exception to be thrown or affect return value. - * @param logger logger, may be null. - * @return true if source file compressed. - * @throws IOException on IO exception. - */ - public static boolean execute( - final File source, final File destination, final boolean deleteSource, - final ULogger logger) throws IOException { - if (source.exists()) { - FileInputStream fis = new FileInputStream(source); - FileOutputStream fos = new FileOutputStream(destination); - GZIPOutputStream gzos = new GZIPOutputStream(fos); - byte[] inbuf = new byte[8102]; - int n; - - while ((n = fis.read(inbuf)) != -1) { - gzos.write(inbuf, 0, n); - } - - gzos.close(); - fis.close(); - - if (deleteSource) { - if (!source.delete() && (logger != null)) { - logger.info("Unable to delete {}.", source.toString()); - } - } - - return true; - } - - return false; - } - - - /** - * Capture exception. - * - * @param ex exception. - */ - protected void reportException(final Exception ex) { - if (logger != null) { - logger.info("Exception during compression of '" + source.toString() + "'.", ex); - } - } - -} diff --git a/src/main/java/org/apache/log4j/rolling/helper/ZipCompressAction.java b/src/main/java/org/apache/log4j/rolling/helper/ZipCompressAction.java deleted file mode 100644 index 48611a8831..0000000000 --- a/src/main/java/org/apache/log4j/rolling/helper/ZipCompressAction.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling.helper; - -import org.apache.log4j.ULogger; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; - -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - - -/** - * Compresses a file using Zip compression. - * - * @author Curt Arnold - * @since 1.3 - */ -public final class ZipCompressAction extends ActionBase { - /** - * Source file. - */ - private final File source; - - /** - * Destination file. - */ - private final File destination; - - /** - * If true, attempt to delete file on completion. - */ - private final boolean deleteSource; - - /** - * Logger to receive diagnostic messages. - */ - private final ULogger logger; - - /** - * Create new instance of GZCompressAction. - * - * @param source file to compress, may not be null. - * @param destination compressed file, may not be null. - * @param deleteSource if true, attempt to delete file on completion. Failure to delete - * does not cause an exception to be thrown or affect return value. - * @param logger logger, may be null. - */ - public ZipCompressAction( - final File source, final File destination, final boolean deleteSource, - final ULogger logger) { - if (source == null) { - throw new NullPointerException("source"); - } - - if (destination == null) { - throw new NullPointerException("destination"); - } - - this.source = source; - this.destination = destination; - this.deleteSource = deleteSource; - this.logger = logger; - } - - /** - * Compress. - * @return true if successfully compressed. - * @throws IOException on IO exception. - */ - public boolean execute() throws IOException { - return execute(source, destination, deleteSource, logger); - } - - /** - * Compress a file. - * - * @param source file to compress, may not be null. - * @param destination compressed file, may not be null. - * @param deleteSource if true, attempt to delete file on completion. Failure to delete - * does not cause an exception to be thrown or affect return value. - * @param logger logger, may be null. - * @return true if source file compressed. - * @throws IOException on IO exception. - */ - public static boolean execute( - final File source, final File destination, final boolean deleteSource, - final ULogger logger) throws IOException { - if (source.exists()) { - FileInputStream fis = new FileInputStream(source); - FileOutputStream fos = new FileOutputStream(destination); - ZipOutputStream zos = new ZipOutputStream(fos); - - ZipEntry zipEntry = new ZipEntry(source.getName()); - zos.putNextEntry(zipEntry); - - byte[] inbuf = new byte[8102]; - int n; - - while ((n = fis.read(inbuf)) != -1) { - zos.write(inbuf, 0, n); - } - - zos.close(); - fis.close(); - - if (deleteSource) { - if (!source.delete() && (logger != null)) { - logger.info("Unable to delete {}.", source.toString()); - } - } - - return true; - } - - return false; - } - - /** - * Capture exception. - * - * @param ex exception. - */ - protected void reportException(final Exception ex) { - if (logger != null) { - logger.info("Exception during compression of '" + source.toString() + "'.", ex); - } - } -} diff --git a/src/main/java/org/apache/log4j/rolling/helper/package.html b/src/main/java/org/apache/log4j/rolling/helper/package.html deleted file mode 100644 index 1aff609c8f..0000000000 --- a/src/main/java/org/apache/log4j/rolling/helper/package.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - -

    Internal helper classes used by {@link org.apache.log4j.rolling} package.

    - -
    - diff --git a/src/main/java/org/apache/log4j/rolling/package.html b/src/main/java/org/apache/log4j/rolling/package.html deleted file mode 100644 index eaf04912d5..0000000000 --- a/src/main/java/org/apache/log4j/rolling/package.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - -

    Implements various file rolling policies.

    - -

    The {@link org.apache.log4j.rolling.RollingFileAppender} class - serves as the linchpin of this package. Its behaviour is - controlled by two subcomponents of type {@link - org.apache.log4j.rolling.RollingPolicy} and {@link - org.apache.log4j.rolling.TriggeringPolicy}. -

    - - - \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/rule/AbstractRule.java b/src/main/java/org/apache/log4j/rule/AbstractRule.java deleted file mode 100644 index f74bf501e1..0000000000 --- a/src/main/java/org/apache/log4j/rule/AbstractRule.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; -import java.io.Serializable; - - -/** - * An abstract Rule class that provides the PropertyChange support plumbing. - * - * @author Paul Smith (psmith@apache.org) - * @author Scott Deboy (sdeboy@apache.org) - */ -public abstract class AbstractRule implements Rule, Serializable { - /** - * Serialization id. - */ - static final long serialVersionUID = -2844288145563025172L; - - /** - * PropertySupport instance. - */ - private PropertyChangeSupport propertySupport = - new PropertyChangeSupport(this); - - /** - * Add property change listener. - * @param l listener. - */ - public void addPropertyChangeListener(final PropertyChangeListener l) { - propertySupport.addPropertyChangeListener(l); - } - - /** - * Remove property change listener. - * @param l listener. - */ - public void removePropertyChangeListener(final PropertyChangeListener l) { - propertySupport.removePropertyChangeListener(l); - } - - /** - * Send property change notification to attached listeners. - * @param propertyName property name. - * @param oldVal old value. - * @param newVal new value. - */ - protected void firePropertyChange( - final String propertyName, - final Object oldVal, - final Object newVal) { - propertySupport.firePropertyChange(propertyName, oldVal, newVal); - } - - /** - * Send property change notification to attached listeners. - * @param evt property change event. - */ - public void firePropertyChange(final PropertyChangeEvent evt) { - propertySupport.firePropertyChange(evt); - } -} diff --git a/src/main/java/org/apache/log4j/rule/AndRule.java b/src/main/java/org/apache/log4j/rule/AndRule.java deleted file mode 100644 index c966d9d9ff..0000000000 --- a/src/main/java/org/apache/log4j/rule/AndRule.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import org.apache.log4j.spi.LoggingEvent; - -import java.util.Stack; - - -/** - * A Rule class implementing a logical 'and'. - * - * @author Scott Deboy (sdeboy@apache.org) - */ -public class AndRule extends AbstractRule { - /** - * First rule. - */ - private final Rule firstRule; - /** - * Second rule. - */ - private final Rule secondRule; - /** - * Serialization id. - */ - static final long serialVersionUID = -8233444426923854651L; - - /** - * Create new instance. - * @param first first rule. - * @param second second rule. - */ - private AndRule(final Rule first, final Rule second) { - super(); - this.firstRule = first; - this.secondRule = second; - } - - /** - * Create rule from top two elements of stack. - * @param stack stack of rules. - * @return Rule that evaluates true only if both rules are true. - */ - public static Rule getRule(final Stack stack) { - if (stack.size() < 2) { - throw new IllegalArgumentException( - "Invalid AND rule - expected two rules but received " - + stack.size()); - } - Object o2 = stack.pop(); - Object o1 = stack.pop(); - if ((o2 instanceof Rule) && (o1 instanceof Rule)) { - Rule p2 = (Rule) o2; - Rule p1 = (Rule) o1; - return new AndRule(p1, p2); - } - throw new IllegalArgumentException("Invalid AND rule: " + o2 + "..." + o1); - } - - /** - * Get rule. - * @param firstParam first rule. - * @param secondParam second rule. - * @return Rule that evaluates true only if both rules are true. - */ - public static Rule getRule(final Rule firstParam, final Rule secondParam) { - return new AndRule(firstParam, secondParam); - } - - /** - * {@inheritDoc} - */ - public boolean evaluate(final LoggingEvent event) { - return (firstRule.evaluate(event) && secondRule.evaluate(event)); - } -} diff --git a/src/main/java/org/apache/log4j/rule/ColorRule.java b/src/main/java/org/apache/log4j/rule/ColorRule.java deleted file mode 100644 index 84f4e96579..0000000000 --- a/src/main/java/org/apache/log4j/rule/ColorRule.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import java.awt.Color; -import java.io.Serializable; - -import org.apache.log4j.spi.LoggingEvent; - - -/** - * A Rule class which also holds a color. - * - * @author Scott Deboy (sdeboy@apache.org) - */ -public class ColorRule extends AbstractRule implements Serializable { - /** - * Serialization id. - */ - static final long serialVersionUID = -794434783372847773L; - - /** - * Wrapped rule. - */ - private final Rule rule; - /** - * Foreground color. - */ - private final Color foregroundColor; - /** - * Background color. - */ - private final Color backgroundColor; - /** - * Expression. - */ - private final String expression; - - /** - * Create new instance. - * @param expression expression. - * @param rule rule. - * @param backgroundColor background color. - * @param foregroundColor foreground color. - */ - public ColorRule(final String expression, - final Rule rule, - final Color backgroundColor, - final Color foregroundColor) { - super(); - this.expression = expression; - this.rule = rule; - this.backgroundColor = backgroundColor; - this.foregroundColor = foregroundColor; - } - - /** - * Get rule. - * @return underlying rule. - */ - public Rule getRule() { - return rule; - } - - /** - * Get foreground color. - * @return foreground color. - */ - public Color getForegroundColor() { - return foregroundColor; - } - - /** - * Get background color. - * @return background color. - */ - public Color getBackgroundColor() { - return backgroundColor; - } - - /** - * Get expression. - * @return expression. - */ - public String getExpression() { - return expression; - } - - /** - * {@inheritDoc} - */ - public boolean evaluate(final LoggingEvent event) { - return (rule != null && rule.evaluate(event)); - } - - /** - * {@inheritDoc} - */ - public String toString() { - StringBuffer buf = new StringBuffer("color rule - expression: "); - buf.append(expression); - buf.append(", rule: "); - buf.append(rule); - buf.append(" bg: "); - buf.append(backgroundColor); - buf.append(" fg: "); - buf.append(foregroundColor); - return buf.toString(); - } -} diff --git a/src/main/java/org/apache/log4j/rule/EqualsRule.java b/src/main/java/org/apache/log4j/rule/EqualsRule.java deleted file mode 100644 index 0e09ee5f2d..0000000000 --- a/src/main/java/org/apache/log4j/rule/EqualsRule.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.LoggingEventFieldResolver; - -import java.util.Stack; - - -/** - * A Rule class which returns the result of - * performing equals against two strings. - * - * @author Scott Deboy (sdeboy@apache.org) - */ -public class EqualsRule extends AbstractRule { - /** - * Serialization ID. - */ - static final long serialVersionUID = 1712851553477517245L; - /** - * Resolver. - */ - private static final LoggingEventFieldResolver RESOLVER = - LoggingEventFieldResolver.getInstance(); - /** - * Value. - */ - private final String value; - /** - * Field. - */ - private final String field; - - /** - * Create new instance. - * @param field field - * @param value value - */ - private EqualsRule(final String field, final String value) { - super(); - if (!RESOLVER.isField(field)) { - throw new IllegalArgumentException( - "Invalid EQUALS rule - " + field + " is not a supported field"); - } - - this.field = field; - this.value = value; - } - - /** - * Create new instance from top two elements of stack. - * @param stack stack - * @return new instance - */ - public static Rule getRule(final Stack stack) { - if (stack.size() < 2) { - throw new IllegalArgumentException( - "Invalid EQUALS rule - expected two parameters but received " - + stack.size()); - } - - String p2 = stack.pop().toString(); - String p1 = stack.pop().toString(); - - return getRule(p1, p2); - } - - /** - * Create new instance. - * @param p1 field, special treatment for level and timestamp. - * @param p2 value - * @return new instance - */ - public static Rule getRule(final String p1, final String p2) { - if (p1.equalsIgnoreCase(LoggingEventFieldResolver.LEVEL_FIELD)) { - return LevelEqualsRule.getRule(p2); - } else if (p1.equalsIgnoreCase(LoggingEventFieldResolver.TIMESTAMP_FIELD)) { - return TimestampEqualsRule.getRule(p2); - } else { - return new EqualsRule(p1, p2); - } - } - - /** {@inheritDoc} */ - public boolean evaluate(final LoggingEvent event) { - Object p2 = RESOLVER.getValue(field, event); - - return ((p2 != null) && p2.toString().equals(value)); - } -} diff --git a/src/main/java/org/apache/log4j/rule/ExistsRule.java b/src/main/java/org/apache/log4j/rule/ExistsRule.java deleted file mode 100644 index 961a6670fa..0000000000 --- a/src/main/java/org/apache/log4j/rule/ExistsRule.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.LoggingEventFieldResolver; - -import java.util.Stack; - - -/** - * A Rule class implementing a not null (and not empty string) check. - * - * @author Scott Deboy (sdeboy@apache.org) - */ -public class ExistsRule extends AbstractRule { - /** - * Serialization id. - */ - static final long serialVersionUID = -5386265224649967464L; - /** - * field resolver. - */ - private static final LoggingEventFieldResolver RESOLVER = - LoggingEventFieldResolver.getInstance(); - /** - * field name. - */ - private final String field; - - /** - * Create new instance. - * @param fld field name. - */ - private ExistsRule(final String fld) { - super(); - if (!RESOLVER.isField(fld)) { - throw new IllegalArgumentException( - "Invalid EXISTS rule - " + fld + " is not a supported field"); - } - - this.field = fld; - } - - /** - * Get an instance of ExistsRule. - * @param field field. - * @return instance of ExistsRule. - */ - public static Rule getRule(final String field) { - return new ExistsRule(field); - } - - /** - * Create an instance of ExistsRule using the - * top name on the stack. - * @param stack stack - * @return instance of ExistsRule. - */ - public static Rule getRule(final Stack stack) { - if (stack.size() < 1) { - throw new IllegalArgumentException( - "Invalid EXISTS rule - expected one parameter but received " - + stack.size()); - } - - return new ExistsRule(stack.pop().toString()); - } - - /** - * {@inheritDoc} - */ - public boolean evaluate(final LoggingEvent event) { - Object p2 = RESOLVER.getValue(field, event); - - return (!((p2 == null) || ((p2 != null) && p2.toString().equals("")))); - } -} diff --git a/src/main/java/org/apache/log4j/rule/ExpressionRule.java b/src/main/java/org/apache/log4j/rule/ExpressionRule.java deleted file mode 100644 index 90271bee69..0000000000 --- a/src/main/java/org/apache/log4j/rule/ExpressionRule.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import org.apache.log4j.spi.LoggingEvent; - -import java.util.Stack; -import java.util.StringTokenizer; - - -/** - * A Rule class supporting both infix and postfix expressions, - * accepting any rule which - * is supported by the RuleFactory. - * - * NOTE: parsing is supported through the use of - * StringTokenizer, which - * implies two limitations: - * 1: all tokens in the expression must be separated by spaces, - * including parenthesis - * 2: operands which contain spaces MUST be wrapped in single quotes. - * For example, the expression: - * msg == 'some msg' - * is a valid expression. - * 3: To group expressions, use parentheses. - * For example, the expression: - * level >= INFO || ( msg == 'some msg' || logger == 'test' ) - * is a valid expression. - * See org.apache.log4j.rule.InFixToPostFix for a - * description of supported operators. - * See org.apache.log4j.spi.LoggingEventFieldResolver for field keywords. - * - * @author Scott Deboy (sdeboy@apache.org) - */ -public class ExpressionRule extends AbstractRule { - /** - * Serialization ID. - */ - static final long serialVersionUID = 5809121703146893729L; - /** - * Converter. - */ - private static final InFixToPostFix CONVERTER = new InFixToPostFix(); - /** - * Compiler. - */ - private static final PostFixExpressionCompiler COMPILER = - new PostFixExpressionCompiler(); - /** - * Rule. - */ - private final Rule rule; - - /** - * Create new instance. - * @param r rule - */ - private ExpressionRule(final Rule r) { - super(); - this.rule = r; - } - - /** - * Get rule. - * @param expression expression. - * @return rule. - */ - public static Rule getRule(final String expression) { - return getRule(expression, false); - } - - /** - * Get rule. - * @param expression expression. - * @param isPostFix If post-fix. - * @return rule - */ - public static Rule getRule(final String expression, - final boolean isPostFix) { - String postFix = expression; - if (!isPostFix) { - postFix = CONVERTER.convert(expression); - } - - return new ExpressionRule(COMPILER.compileExpression(postFix)); - } - - /** - * {@inheritDoc} - */ - public boolean evaluate(final LoggingEvent event) { - return rule.evaluate(event); - } - - /** - * {@inheritDoc} - */ - public String toString() { - return rule.toString(); - } - - /** - * Evaluate a boolean postfix expression. - * - */ - static final class PostFixExpressionCompiler { - /** - * Compile expression. - * @param expression expression. - * @return rule. - */ - public Rule compileExpression(final String expression) { - RuleFactory factory = RuleFactory.getInstance(); - - Stack stack = new Stack(); - StringTokenizer tokenizer = new StringTokenizer(expression); - - while (tokenizer.hasMoreTokens()) { - //examine each token - String token = tokenizer.nextToken(); - if ((token.startsWith("'")) - && (token.endsWith("'") - && (token.length() > 2))) { - token = token.substring(1, token.length() - 1); - } - if ((token.startsWith("'")) - && (token.endsWith("'") - && (token.length() == 2))) { - token = ""; - } - - boolean inText = token.startsWith("'"); - if (inText) { - token = token.substring(1); - while (inText && tokenizer.hasMoreTokens()) { - token = token + " " + tokenizer.nextToken(); - inText = !(token.endsWith("'")); - } - if (token.length() > 0) { - token = token.substring(0, token.length() - 1); - } - } - - //if a symbol is found, pop 2 off the stack, - // evaluate and push the result - if (factory.isRule(token)) { - Rule r = factory.getRule(token, stack); - stack.push(r); - } else { - //variables or constants are pushed onto the stack - if (token.length() > 0) { - stack.push(token); - } - } - } - - if ((stack.size() == 1) && (!(stack.peek() instanceof Rule))) { - //while this may be an attempt at creating an expression, - //for ease of use, convert this single entry to a partial-text - //match on the MSG field - Object o = stack.pop(); - stack.push("MSG"); - stack.push(o); - return factory.getRule("~=", stack); - } - - //stack should contain a single rule if the expression is valid - if ((stack.size() != 1) || (!(stack.peek() instanceof Rule))) { - throw new IllegalArgumentException("invalid expression: " + expression); - } else { - return (Rule) stack.pop(); - } - } - } -} - - diff --git a/src/main/java/org/apache/log4j/rule/InFixToPostFix.java b/src/main/java/org/apache/log4j/rule/InFixToPostFix.java deleted file mode 100644 index 9c9c7e674b..0000000000 --- a/src/main/java/org/apache/log4j/rule/InFixToPostFix.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Stack; -import java.util.StringTokenizer; -import java.util.Vector; - -/** - * A helper class which converts infix expressions to postfix expressions - * Currently grouping is supported, as well as all of the - * Rules supported by RuleFactory - * - * NOTE: parsing is supported through the use of StringTokenizer, - * which means all tokens in the expression must be separated by spaces. - * - * Supports grouping via parens, mult-word operands using single quotes, - * and these operators: - * - * ! NOT operator - * != NOT EQUALS operator - * == EQUALS operator - * ~= CASE-INSENSITIVE equals operator - * || OR operator - * && AND operator - * like REGEXP operator - * exists NOT NULL operator - * < LESS THAN operator - * > GREATER THAN operator - * <= LESS THAN EQUALS operator - * >= GREATER THAN EQUALS operator - * - * @author Scott Deboy (sdeboy@apache.org) - */ - -public class InFixToPostFix { - /** - * Precedence map. - */ - private final Map precedenceMap = new HashMap(); - /** - * Operators. - */ - private final List operators = new Vector(); - - /** - * Create new instance. - */ - public InFixToPostFix() { - super(); - //boolean operators - operators.add("!"); - operators.add("!="); - operators.add("=="); - operators.add("~="); - operators.add("||"); - operators.add("&&"); - operators.add("like"); - operators.add("exists"); - operators.add("<"); - operators.add(">"); - operators.add("<="); - operators.add(">="); - - //boolean precedence - precedenceMap.put("<", new Integer(3)); - precedenceMap.put(">", new Integer(3)); - precedenceMap.put("<=", new Integer(3)); - precedenceMap.put(">=", new Integer(3)); - - precedenceMap.put("!", new Integer(3)); - precedenceMap.put("!=", new Integer(3)); - precedenceMap.put("==", new Integer(3)); - precedenceMap.put("~=", new Integer(3)); - precedenceMap.put("like", new Integer(3)); - precedenceMap.put("exists", new Integer(3)); - - precedenceMap.put("||", new Integer(2)); - precedenceMap.put("&&", new Integer(2)); - } - - /** - * Convert in-fix expression to post-fix. - * @param expression in-fix expression. - * @return post-fix expression. - */ - public String convert(final String expression) { - return infixToPostFix(new StringTokenizer(expression)); - } - - /** - * Evaluates whether symbol is operand. - * @param s symbol. - * @return true if operand. - */ - boolean isOperand(final String s) { - String symbol = s.toLowerCase(); - return (!operators.contains(symbol)); - } - - /** - * Determines whether one symbol precedes another. - * @param s1 symbol 1 - * @param s2 symbol 2 - * @return true if symbol 1 precedes symbol 2 - */ - boolean precedes(final String s1, final String s2) { - String symbol1 = s1.toLowerCase(); - String symbol2 = s2.toLowerCase(); - - if (!precedenceMap.keySet().contains(symbol1)) { - return false; - } - - if (!precedenceMap.keySet().contains(symbol2)) { - return false; - } - - int index1 = ((Integer) precedenceMap.get(symbol1)).intValue(); - int index2 = ((Integer) precedenceMap.get(symbol2)).intValue(); - - boolean precedesResult = (index1 < index2); - - return precedesResult; - } - - /** - * convert in-fix expression to post-fix. - * @param tokenizer tokenizer. - * @return post-fix expression. - */ - String infixToPostFix(final StringTokenizer tokenizer) { - final String space = " "; - StringBuffer postfix = new StringBuffer(); - - Stack stack = new Stack(); - - while (tokenizer.hasMoreTokens()) { - String token = tokenizer.nextToken(); - - boolean inText = (token.startsWith("'") && (!token.endsWith("'"))); - if (inText) { - while (inText && tokenizer.hasMoreTokens()) { - token = token + " " + tokenizer.nextToken(); - inText = !(token.endsWith("'")); - } - } - - if ("(".equals(token)) { - //recurse - postfix.append(infixToPostFix(tokenizer)); - postfix.append(space); - } else if (")".equals(token)) { - //exit recursion level - while (stack.size() > 0) { - postfix.append(stack.pop().toString()); - postfix.append(space); - } - - return postfix.toString(); - } else if (isOperand(token)) { - postfix.append(token); - postfix.append(space); - } else { - //operator.. - //peek the stack..if the top element has a lower precedence than token - //(peeked + has lower precedence than token *), - // push token onto the stack - //otherwise, pop top element off stack and add to postfix string - //in a loop until lower precedence or empty..then push token - if (stack.size() > 0) { - - String peek = stack.peek().toString(); - - if (precedes(peek, token)) { - stack.push(token); - } else { - boolean bypass = false; - - do { - if ( - (stack.size() > 0) - && !precedes(stack.peek().toString(), token)) { - postfix.append(stack.pop().toString()); - postfix.append(space); - } else { - bypass = true; - } - } while (!bypass); - - stack.push(token); - } - } else { - stack.push(token); - } - } - } - - while (stack.size() > 0) { - postfix.append(stack.pop().toString()); - postfix.append(space); - } - - return postfix.toString(); - } -} diff --git a/src/main/java/org/apache/log4j/rule/InequalityRule.java b/src/main/java/org/apache/log4j/rule/InequalityRule.java deleted file mode 100644 index acfa87c85e..0000000000 --- a/src/main/java/org/apache/log4j/rule/InequalityRule.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.LoggingEventFieldResolver; - -import java.util.Stack; - - -/** - * A Rule class implementing inequality evaluation. - * expects to be able to convert two values to longs. - * If a specific inequality evaluation class has been provided - * for the event field, the appropriate rule is returned. - * (For example, if the expression is Level < DEBUG, - * a LevelInequalityRule is returned). - * - * @author Scott Deboy (sdeboy@apache.org) - */ -public class InequalityRule extends AbstractRule { - /** - * Serialization ID. - */ - static final long serialVersionUID = -5592986598528885122L; - /** - * field RESOLVER. - */ - private static final LoggingEventFieldResolver RESOLVER = - LoggingEventFieldResolver.getInstance(); - /** - * Field name. - */ - private final String field; - /** - * Comparison value. - */ - private final String value; - /** - * Inequality symbol. - */ - private final String inequalitySymbol; - - /** - * Create new instance. - * @param inequalitySymbol inequality symbol. - * @param field field - * @param value comparison value. - */ - private InequalityRule( - final String inequalitySymbol, - final String field, - final String value) { - super(); - this.inequalitySymbol = inequalitySymbol; - if (!RESOLVER.isField(field)) { - throw new IllegalArgumentException("Invalid " + inequalitySymbol - + " rule - " + field + " is not a supported field"); - } - - this.field = field; - this.value = value; - } - - /** - * Create new instance from top two elements on stack. - * @param inequalitySymbol inequality symbol. - * @param stack stack. - * @return rule. - */ - public static Rule getRule(final String inequalitySymbol, - final Stack stack) { - if (stack.size() < 2) { - throw new IllegalArgumentException("Invalid " + inequalitySymbol - + " rule - expected two parameters but received " - + stack.size()); - } - - String p2 = stack.pop().toString(); - String p1 = stack.pop().toString(); - return getRule(inequalitySymbol, p1, p2); - } - - /** - * Create new instance from top two elements on stack. - * @param inequalitySymbol inequality symbol. - * @param field field. - * @param value comparison value. - * @return rule. - */ - public static Rule getRule(final String inequalitySymbol, - final String field, - final String value) { - if (field.equalsIgnoreCase(LoggingEventFieldResolver.LEVEL_FIELD)) { - //push the value back on the stack and - // allow the level-specific rule pop values - return LevelInequalityRule.getRule(inequalitySymbol, value); - } else if ( - field.equalsIgnoreCase(LoggingEventFieldResolver.TIMESTAMP_FIELD)) { - return TimestampInequalityRule.getRule(inequalitySymbol, value); - } else { - return new InequalityRule(inequalitySymbol, field, value); - } - } - - /** {@inheritDoc} */ - public boolean evaluate(final LoggingEvent event) { - long first = 0; - - try { - first = - new Long(RESOLVER.getValue(field, event).toString()).longValue(); - } catch (NumberFormatException nfe) { - return false; - } - - long second = 0; - - try { - second = new Long(value).longValue(); - } catch (NumberFormatException nfe) { - return false; - } - - boolean result = false; - - if ("<".equals(inequalitySymbol)) { - result = first < second; - } else if (">".equals(inequalitySymbol)) { - result = first > second; - } else if ("<=".equals(inequalitySymbol)) { - result = first <= second; - } else if (">=".equals(inequalitySymbol)) { - result = first >= second; - } - - return result; - } -} diff --git a/src/main/java/org/apache/log4j/rule/LevelEqualsRule.java b/src/main/java/org/apache/log4j/rule/LevelEqualsRule.java deleted file mode 100644 index e545fd5ed1..0000000000 --- a/src/main/java/org/apache/log4j/rule/LevelEqualsRule.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; - -import org.apache.log4j.Level; -import org.apache.log4j.helpers.UtilLoggingLevel; -import org.apache.log4j.spi.LoggingEvent; - -/** - * A Rule class implementing equals against two levels. - * - * @author Scott Deboy (sdeboy@apache.org) - */ -public class LevelEqualsRule extends AbstractRule { - /** - * Serialization ID. - */ - static final long serialVersionUID = -3638386582899583994L; - - /** - * Level. - */ - private transient Level level; - - /** - * List of levels. - */ - private static List levelList = new LinkedList(); - - static { - populateLevels(); - } - - /** - * Create new instance. - * @param level level. - */ - private LevelEqualsRule(final Level level) { - super(); - this.level = level; - } - - /** - * Populate list of levels. - */ - private static void populateLevels() { - levelList = new LinkedList(); - - levelList.add(Level.FATAL.toString()); - levelList.add(Level.ERROR.toString()); - levelList.add(Level.WARN.toString()); - levelList.add(Level.INFO.toString()); - levelList.add(Level.DEBUG.toString()); - levelList.add(Level.TRACE.toString()); - } - - /** - * Create new rule. - * @param value name of level. - * @return instance of LevelEqualsRule. - */ - public static Rule getRule(final String value) { - Level thisLevel; - if (levelList.contains(value.toUpperCase())) { - thisLevel = Level.toLevel(value.toUpperCase()); - } else { - thisLevel = UtilLoggingLevel.toLevel(value.toUpperCase()); - } - - return new LevelEqualsRule(thisLevel); - } - - /** - * {@inheritDoc} - */ - public boolean evaluate(final LoggingEvent event) { - return level.equals(event.getLevel()); - } - - /** - * Deserialize the state of the object. - * - * @param in object input stream. - * - * @throws IOException if error in reading stream for deserialization. - */ - private void readObject(final java.io.ObjectInputStream in) - throws IOException { - populateLevels(); - boolean isUtilLogging = in.readBoolean(); - int levelInt = in.readInt(); - if (isUtilLogging) { - level = UtilLoggingLevel.toLevel(levelInt); - } else { - level = Level.toLevel(levelInt); - } - } - - /** - * Serialize the state of the object. - * - * @param out object output stream. - * - * @throws IOException if error in writing stream during serialization. - */ - private void writeObject(final java.io.ObjectOutputStream out) - throws IOException { - out.writeBoolean(level instanceof UtilLoggingLevel); - out.writeInt(level.toInt()); - } -} diff --git a/src/main/java/org/apache/log4j/rule/LevelInequalityRule.java b/src/main/java/org/apache/log4j/rule/LevelInequalityRule.java deleted file mode 100644 index 9658b004b1..0000000000 --- a/src/main/java/org/apache/log4j/rule/LevelInequalityRule.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import java.util.LinkedList; -import java.util.List; - -import org.apache.log4j.Level; -import org.apache.log4j.helpers.UtilLoggingLevel; -import org.apache.log4j.spi.LoggingEvent; - -/** - * A Rule class implementing inequality evaluation for Levels (log4j and - * util.logging) using the toInt method. - * - * @author Scott Deboy (sdeboy@apache.org) - */ -public class LevelInequalityRule { - /** - * Level list. - */ - private static List levelList; - /** - * List equivalents of java.util.logging levels. - */ - private static List utilLoggingLevelList; - - - static { - populateLevels(); - } - - /** - * Create new instance. - */ - private LevelInequalityRule() { - super(); - } - - /** - * Populate list of levels. - */ - private static void populateLevels() { - levelList = new LinkedList(); - - levelList.add(Level.FATAL.toString()); - levelList.add(Level.ERROR.toString()); - levelList.add(Level.WARN.toString()); - levelList.add(Level.INFO.toString()); - levelList.add(Level.DEBUG.toString()); - levelList.add(Level.TRACE.toString()); - - utilLoggingLevelList = new LinkedList(); - - utilLoggingLevelList.add(UtilLoggingLevel.SEVERE.toString()); - utilLoggingLevelList.add(UtilLoggingLevel.WARNING.toString()); - utilLoggingLevelList.add(UtilLoggingLevel.INFO.toString()); - utilLoggingLevelList.add(UtilLoggingLevel.CONFIG.toString()); - utilLoggingLevelList.add(UtilLoggingLevel.FINE.toString()); - utilLoggingLevelList.add(UtilLoggingLevel.FINER.toString()); - utilLoggingLevelList.add(UtilLoggingLevel.FINEST.toString()); - - } - - /** - * Create new rule. - * @param inequalitySymbol inequality symbol. - * @param value Symbolic name of comparison level. - * @return instance of AbstractRule. - */ - public static Rule getRule(final String inequalitySymbol, - final String value) { - - Level thisLevel; - - //if valid util.logging levels are used against events - // with log4j levels, the - //DEBUG level is used and an illegalargumentexception won't be generated - - //an illegalargumentexception is only generated - // if the user types a level name - //that doesn't exist as either a log4j or util.logging level name - if (levelList.contains(value.toUpperCase())) { - thisLevel = Level.toLevel(value.toUpperCase()); - } else if (utilLoggingLevelList.contains(value.toUpperCase())) { - thisLevel = UtilLoggingLevel.toLevel(value.toUpperCase()); - } else { - throw new IllegalArgumentException( - "Invalid level inequality rule - " + value - + " is not a supported level"); - } - - if ("<".equals(inequalitySymbol)) { - return new LessThanRule(thisLevel); - } - if (">".equals(inequalitySymbol)) { - return new GreaterThanRule(thisLevel); - } - if ("<=".equals(inequalitySymbol)) { - return new LessThanEqualsRule(thisLevel); - } - if (">=".equals(inequalitySymbol)) { - return new GreaterThanEqualsRule(thisLevel); - } - - return null; - } - - /** - * Rule returning true if event level less than specified level. - */ - private static final class LessThanRule extends AbstractRule { - /** - * Comparison level. - */ - private final int newLevelInt; - - /** - * Create new instance. - * @param level comparison level. - */ - public LessThanRule(final Level level) { - super(); - newLevelInt = level.toInt(); - } - - /** {@inheritDoc} */ - public boolean evaluate(final LoggingEvent event) { - return (event.getLevel().toInt() < newLevelInt); - } - } - - /** - * Rule returning true if event level greater than specified level. - */ - private static final class GreaterThanRule extends AbstractRule { - /** - * Comparison level. - */ - private final int newLevelInt; - - /** - * Create new instance. - * @param level comparison level. - */ - public GreaterThanRule(final Level level) { - super(); - newLevelInt = level.toInt(); - } - - /** {@inheritDoc} */ - public boolean evaluate(final LoggingEvent event) { - return (event.getLevel().toInt() > newLevelInt); - } - } - - /** - * Rule returning true if event level greater than - * or equal to specified level. - */ - private static final class GreaterThanEqualsRule extends AbstractRule { - /** - * Comparison level. - */ - private final int newLevelInt; - - /** - * Create new instance. - * @param level comparison level. - */ - public GreaterThanEqualsRule(final Level level) { - super(); - newLevelInt = level.toInt(); - } - - /** {@inheritDoc} */ - public boolean evaluate(final LoggingEvent event) { - return event.getLevel().toInt() >= newLevelInt; - } - } - - /** - * Rule returning true if event level less than or - * equal to specified level. - */ - - private static final class LessThanEqualsRule extends AbstractRule { - /** - * Comparison level. - */ - private final int newLevelInt; - - /** - * Create new instance. - * @param level comparison level. - */ - public LessThanEqualsRule(final Level level) { - super(); - newLevelInt = level.toInt(); - } - - /** {@inheritDoc} */ - public boolean evaluate(final LoggingEvent event) { - return (event.getLevel().toInt() <= newLevelInt); - } - } -} diff --git a/src/main/java/org/apache/log4j/rule/LikeRule.java b/src/main/java/org/apache/log4j/rule/LikeRule.java deleted file mode 100644 index 0c5f516df0..0000000000 --- a/src/main/java/org/apache/log4j/rule/LikeRule.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import java.io.IOException; -import java.util.Stack; - -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.LoggingEventFieldResolver; -import org.apache.oro.text.regex.MalformedPatternException; -import org.apache.oro.text.regex.Pattern; -import org.apache.oro.text.regex.Perl5Compiler; -import org.apache.oro.text.regex.Perl5Matcher; - -/** - * A Rule class providing support for ORO-based regular expression syntax. - * - * @author Scott Deboy (sdeboy@apache.org) - */ -public class LikeRule extends AbstractRule { - /** - * Serialization ID. - */ - static final long serialVersionUID = -3375458885595683156L; - - /** - * Resolver. - */ - private static final LoggingEventFieldResolver RESOLVER = - LoggingEventFieldResolver.getInstance(); - /** - * Pattern. - */ - private transient Pattern pattern; - /** - * Regular expression matcher. - */ - private transient Perl5Matcher matcher = new Perl5Matcher(); - /** - * Field. - */ - private transient String field; - - /** - * Create new instance. - * @param field field - * @param pattern pattern - */ - private LikeRule(final String field, final Pattern pattern) { - super(); - if (!RESOLVER.isField(field)) { - throw new IllegalArgumentException( - "Invalid LIKE rule - " + field + " is not a supported field"); - } - - this.field = field; - this.pattern = pattern; - } - - /** - * Create new instance from top two elements of stack. - * @param stack stack - * @return new instance - */ - public static Rule getRule(final Stack stack) { - if (stack.size() < 2) { - throw new IllegalArgumentException( - "Invalid LIKE rule - expected two parameters but received " - + stack.size()); - } - - String p2 = stack.pop().toString(); - String p1 = stack.pop().toString(); - return getRule(p1, p2); - } - - /** - * Create new instance. - * @param field field - * @param pattern pattern - * @return new instance - */ - public static Rule getRule(final String field, final String pattern) { - Perl5Compiler compiler = new Perl5Compiler(); - Pattern pattern1 = null; - - try { - pattern1 = compiler.compile(pattern, Perl5Compiler.CASE_INSENSITIVE_MASK); - } catch (MalformedPatternException e) { - throw new IllegalArgumentException( - "Invalid LIKE rule - " + e.getMessage()); - } - - return new LikeRule(field, pattern1); - } - - /** {@inheritDoc} */ - public boolean evaluate(final LoggingEvent event) { - Object input = RESOLVER.getValue(field, event); - return ((input != null) && (pattern != null) - && (matcher.matches(input.toString(), pattern))); - } - - /** - * Deserialize the state of the object. - * - * @param in object input stream - * - * @throws IOException if IOException during deserialization - * @throws ClassNotFoundException if class not found. - */ - private void readObject(final java.io.ObjectInputStream in) - throws IOException, ClassNotFoundException { - try { - field = (String) in.readObject(); - String patternString = (String) in.readObject(); - Perl5Compiler compiler = new Perl5Compiler(); - matcher = new Perl5Matcher(); - pattern = compiler.compile(patternString, - Perl5Compiler.CASE_INSENSITIVE_MASK); - } catch (MalformedPatternException e) { - throw new IOException("Invalid LIKE rule - " + e.getMessage()); - } - } - - /** - * Serialize the state of the object. - * - * @param out object output stream - * - * @throws IOException if IOException during serialization - */ - private void writeObject(final java.io.ObjectOutputStream out) - throws IOException { - out.writeObject(field); - out.writeObject(pattern.getPattern()); - } -} diff --git a/src/main/java/org/apache/log4j/rule/NotEqualsRule.java b/src/main/java/org/apache/log4j/rule/NotEqualsRule.java deleted file mode 100644 index dcf045a06d..0000000000 --- a/src/main/java/org/apache/log4j/rule/NotEqualsRule.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.LoggingEventFieldResolver; - -import java.util.Stack; - - -/** - * A Rule class implementing not equals against two strings. - * - * @author Scott Deboy (sdeboy@apache.org) - */ -public class NotEqualsRule extends AbstractRule { - /** - * Serialization ID. - */ - static final long serialVersionUID = -1135478467213793211L; - /** - * Resolver. - */ - private static final LoggingEventFieldResolver RESOLVER = - LoggingEventFieldResolver.getInstance(); - /** - * Field. - */ - private final String field; - /** - * Value. - */ - private final String value; - - /** - * Create new instance. - * @param field field - * @param value value - */ - private NotEqualsRule(final String field, final String value) { - super(); - if (!RESOLVER.isField(field)) { - throw new IllegalArgumentException( - "Invalid NOT EQUALS rule - " + field + " is not a supported field"); - } - - this.field = field; - this.value = value; - } - - /** - * Get new instance. - * @param field field - * @param value value - * @return new instance. - */ - public static Rule getRule(final String field, final String value) { - return new NotEqualsRule(field, value); - } - - /** - * Get new instance from top two elements of stack. - * @param stack stack. - * @return new instance. - */ - public static Rule getRule(final Stack stack) { - if (stack.size() < 2) { - throw new IllegalArgumentException( - "Invalid NOT EQUALS rule - expected two parameters but received " - + stack.size()); - } - - String p2 = stack.pop().toString(); - String p1 = stack.pop().toString(); - - return new NotEqualsRule(p1, p2); - } - - /** {@inheritDoc} */ - public boolean evaluate(final LoggingEvent event) { - Object p2 = RESOLVER.getValue(field, event); - - return ((p2 != null) && !(p2.toString().equals(value))); - } -} diff --git a/src/main/java/org/apache/log4j/rule/NotRule.java b/src/main/java/org/apache/log4j/rule/NotRule.java deleted file mode 100644 index 4d83232213..0000000000 --- a/src/main/java/org/apache/log4j/rule/NotRule.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import org.apache.log4j.spi.LoggingEvent; - -import java.util.Stack; - -/** - * A Rule class implementing logical not. - * - * @author Scott Deboy (sdeboy@apache.org) - */ -public class NotRule extends AbstractRule { - /** - * Serialization ID. - */ - static final long serialVersionUID = -6827159473117969306L; - /** - * Enclosed rule. - */ - private final Rule rule; - - /** - * Create new instance. - * @param rule enclosed rule. - */ - private NotRule(final Rule rule) { - super(); - this.rule = rule; - } - - /** - * Create new instance. - * @param rule enclosed rule. - * @return new rule. - */ - public static Rule getRule(final Rule rule) { - return new NotRule(rule); - } - - /** - * Create new instance from top element of stack. - * @param stack stack - * @return new rule. - */ - public static Rule getRule(final Stack stack) { - if (stack.size() < 1) { - throw new IllegalArgumentException( - "Invalid NOT rule - expected one rule but received " - + stack.size()); - } - Object o1 = stack.pop(); - if (o1 instanceof Rule) { - Rule p1 = (Rule) o1; - return new NotRule(p1); - } - throw new IllegalArgumentException( - "Invalid NOT rule: - expected rule but received " + o1); - } - - /** {@inheritDoc} */ - public boolean evaluate(final LoggingEvent event) { - return !(rule.evaluate(event)); - } -} diff --git a/src/main/java/org/apache/log4j/rule/OrRule.java b/src/main/java/org/apache/log4j/rule/OrRule.java deleted file mode 100644 index 33ade20d9b..0000000000 --- a/src/main/java/org/apache/log4j/rule/OrRule.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import org.apache.log4j.spi.LoggingEvent; - -import java.util.Stack; - -/** - * A Rule class implementing logical or. - * - * @author Scott Deboy (sdeboy@apache.org) - */ -public class OrRule extends AbstractRule { - /** - * Serialization ID. - */ - static final long serialVersionUID = 2088765995061413165L; - /** - * rule 1. - */ - private final Rule rule1; - /** - * Rule 2. - */ - private final Rule rule2; - - /** - * Create new instance. - * @param firstParam first rule - * @param secondParam second rule - */ - private OrRule(final Rule firstParam, final Rule secondParam) { - super(); - this.rule1 = firstParam; - this.rule2 = secondParam; - } - - /** - * Create new instance. - * @param firstParam first rule - * @param secondParam second rule - * @return new instance - */ - public static Rule getRule(final Rule firstParam, final Rule secondParam) { - return new OrRule(firstParam, secondParam); - } - - /** - * Create new instance from top two elements of stack. - * @param stack stack - * @return new instance - */ - public static Rule getRule(final Stack stack) { - if (stack.size() < 2) { - throw new IllegalArgumentException( - "Invalid OR rule - expected two rules but received " - + stack.size()); - } - Object o2 = stack.pop(); - Object o1 = stack.pop(); - if ((o2 instanceof Rule) && (o1 instanceof Rule)) { - Rule p2 = (Rule) o2; - Rule p1 = (Rule) o1; - return new OrRule(p1, p2); - } - throw new IllegalArgumentException("Invalid OR rule: " + o2 + "..." + o1); - } - - /** {@inheritDoc} */ - public boolean evaluate(final LoggingEvent event) { - return (rule1.evaluate(event) || rule2.evaluate(event)); - } -} diff --git a/src/main/java/org/apache/log4j/rule/PartialTextMatchRule.java b/src/main/java/org/apache/log4j/rule/PartialTextMatchRule.java deleted file mode 100644 index df7c6cdb3c..0000000000 --- a/src/main/java/org/apache/log4j/rule/PartialTextMatchRule.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.LoggingEventFieldResolver; - -import java.util.Stack; - - -/** - * A Rule class implementing case-insensitive - * partial-text matches against two strings. - * - * @author Scott Deboy (sdeboy@apache.org) - */ -public class PartialTextMatchRule extends AbstractRule { - /** - * Serialization ID. - */ - static final long serialVersionUID = 6963284773637727558L; - /** - * Resolver. - */ - private static final LoggingEventFieldResolver RESOLVER = - LoggingEventFieldResolver.getInstance(); - /** - * Field. - */ - private final String field; - /** - * Value. - */ - private final String value; - - /** - * Create new instance. - * @param field field - * @param value value - */ - private PartialTextMatchRule(final String field, final String value) { - super(); - if (!RESOLVER.isField(field)) { - throw new IllegalArgumentException( - "Invalid partial text rule - " + field + " is not a supported field"); - } - - this.field = field; - this.value = value; - } - - /** - * Create new instance. - * @param field field - * @param value value - * @return new instance - */ - public static Rule getRule(final String field, final String value) { - return new PartialTextMatchRule(field, value); - } - - /** - * Create new instance from top two elements of stack. - * @param stack stack - * @return new instance - */ - public static Rule getRule(final Stack stack) { - if (stack.size() < 2) { - throw new IllegalArgumentException( - "invalid partial text rule - expected two parameters but received " - + stack.size()); - } - - String p2 = stack.pop().toString(); - String p1 = stack.pop().toString(); - - return new PartialTextMatchRule(p1, p2); - } - - /** {@inheritDoc} */ - public boolean evaluate(final LoggingEvent event) { - Object p2 = RESOLVER.getValue(field, event); - - return ((p2 != null) && (value != null) - && (p2.toString().toLowerCase().indexOf(value.toLowerCase()) > -1)); - } -} diff --git a/src/main/java/org/apache/log4j/rule/Rule.java b/src/main/java/org/apache/log4j/rule/Rule.java deleted file mode 100644 index 1177c5ed57..0000000000 --- a/src/main/java/org/apache/log4j/rule/Rule.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - */ -package org.apache.log4j.rule; - -import org.apache.log4j.spi.LoggingEvent; - -import java.beans.PropertyChangeListener; - - -/** - * A Rule evaluates to true of false given a LoggingEvent object, and can notify - * listeners when the underlying implementation of this Rule has it's - * criteria changed by using the standard PropertyChangeListener infrastructure. - * - * @author Paul Smith (psmith@apache.org) - * @author Scott Deboy (sdeboy@apache.org) - */ -public interface Rule { - /** - * Returns true if this implementation of the rule accepts the LoggingEvent, - * or false if not. - * - *

    What True/False means can be client-specific. - * - * @param e LoggingEvent this instance will evaluate - * @return true if this Rule instance accepts the event, otherwise false. - */ - boolean evaluate(LoggingEvent e); - - /** - * Adds a PropertyChangeListener to this instance, which is notified when - * underlying Rule information has changed. - * (there are no specific property name events). - * @param listener listener - */ - void addPropertyChangeListener(PropertyChangeListener listener); - - /** - * Removes a known PropertyChangeListener from this Rule. - * @param listener listener - */ - void removePropertyChangeListener(PropertyChangeListener listener); -} diff --git a/src/main/java/org/apache/log4j/rule/RuleFactory.java b/src/main/java/org/apache/log4j/rule/RuleFactory.java deleted file mode 100644 index 2f52c98210..0000000000 --- a/src/main/java/org/apache/log4j/rule/RuleFactory.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.LinkedList; -import java.util.Stack; -import org.apache.log4j.LogManager; - -/** - * A Factory class which, given a string representation of the rule, - * and a context stack, will - * return a Rule ready for evaluation against events. - * If an operator is requested that isn't supported, - * or if a LIKE rule is requested and the ORO package - * is not available, an IllegalArgumentException is thrown. - * - * @author Scott Deboy (sdeboy@apache.org) - */ -public final class RuleFactory { - /** - * Singleton instance. - */ - private static final RuleFactory FACTORY = new RuleFactory(); - /** - * Rules. - */ - private static final Collection RULES = new LinkedList(); - /** - * AND operator literal. - */ - private static final String AND_RULE = "&&"; - /** - * OR operator literal. - */ - private static final String OR_RULE = "||"; - /** - * NOT operator literal. - */ - private static final String NOT_RULE = "!"; - /** - * Inequality operator literal. - */ - private static final String NOT_EQUALS_RULE = "!="; - /** - * Equality operator literal. - */ - private static final String EQUALS_RULE = "=="; - /** - * Partial match operator literal. - */ - private static final String PARTIAL_TEXT_MATCH_RULE = "~="; - /** - * Like operator literal. - */ - private static final String LIKE_RULE = "like"; - /** - * Exists operator literal. - */ - private static final String EXISTS_RULE = "exists"; - /** - * Less than operator literal. - */ - private static final String LESS_THAN_RULE = "<"; - /** - * Greater than operator literal. - */ - private static final String GREATER_THAN_RULE = ">"; - /** - * Less than or equal operator literal. - */ - private static final String LESS_THAN_EQUALS_RULE = "<="; - /** - * Greater than or equal operator literal. - */ - private static final String GREATER_THAN_EQUALS_RULE = ">="; - - static { - RULES.add(AND_RULE); - RULES.add(OR_RULE); - RULES.add(NOT_RULE); - RULES.add(NOT_EQUALS_RULE); - RULES.add(EQUALS_RULE); - RULES.add(PARTIAL_TEXT_MATCH_RULE); - try { - Class.forName("org.apache.log4j.rule.LikeRule"); - RULES.add(LIKE_RULE); - } catch (Exception e) { - LogManager.getLogger(RuleFactory.class).info( - "Like (regular expression) rule not supported"); - } - - RULES.add(EXISTS_RULE); - RULES.add(LESS_THAN_RULE); - RULES.add(GREATER_THAN_RULE); - RULES.add(LESS_THAN_EQUALS_RULE); - RULES.add(GREATER_THAN_EQUALS_RULE); - } - - /** - * Create instance. - */ - private RuleFactory() { - super(); - } - - /** - * Get instance. - * @return rule factory instance. - */ - public static RuleFactory getInstance() { - return FACTORY; - } - - /** - * Determine if specified string is a known operator. - * @param symbol string - * @return true if string is a known operator - */ - public boolean isRule(final String symbol) { - return ((symbol != null) && (RULES.contains(symbol.toLowerCase()))); - } - - /** - * Create rule from applying operator to stack. - * @param symbol symbol - * @param stack stack - * @return new instance - */ - public Rule getRule(final String symbol, final Stack stack) { - if (AND_RULE.equals(symbol)) { - return AndRule.getRule(stack); - } - - if (OR_RULE.equals(symbol)) { - return OrRule.getRule(stack); - } - - if (NOT_RULE.equals(symbol)) { - return NotRule.getRule(stack); - } - - if (NOT_EQUALS_RULE.equals(symbol)) { - return NotEqualsRule.getRule(stack); - } - - if (EQUALS_RULE.equals(symbol)) { - return EqualsRule.getRule(stack); - } - - if (PARTIAL_TEXT_MATCH_RULE.equals(symbol)) { - return PartialTextMatchRule.getRule(stack); - } - - //in order to avoid compile-time dependency on LikeRule, - // call getRule(stack) using reflection - if (RULES.contains(LIKE_RULE) && LIKE_RULE.equalsIgnoreCase(symbol)) { - String methodName = "getRule"; - try { - Class likeClass = Class.forName("org.apache.log4j.rule.LikeRule"); - Method method = - likeClass.getDeclaredMethod(methodName, new Class[]{Stack.class}); - - return (Rule) method.invoke(null, new Object[]{stack}); - } catch (ClassNotFoundException cnfe) { - throw new IllegalArgumentException("Invalid rule: " + symbol); - } catch (NoSuchMethodException nsme) { - throw new IllegalArgumentException("Invalid rule: " + symbol); - } catch (IllegalAccessException iae) { - throw new IllegalArgumentException("Invalid rule: " + symbol); - } catch (InvocationTargetException iae) { - throw new IllegalArgumentException("Invalid rule: " + symbol); - } - } - - if (EXISTS_RULE.equalsIgnoreCase(symbol)) { - return ExistsRule.getRule(stack); - } - - if (LESS_THAN_RULE.equals(symbol)) { - return InequalityRule.getRule(LESS_THAN_RULE, stack); - } - - if (GREATER_THAN_RULE.equals(symbol)) { - return InequalityRule.getRule(GREATER_THAN_RULE, stack); - } - - if (LESS_THAN_EQUALS_RULE.equals(symbol)) { - return InequalityRule.getRule(LESS_THAN_EQUALS_RULE, stack); - } - - if (GREATER_THAN_EQUALS_RULE.equals(symbol)) { - return InequalityRule.getRule(GREATER_THAN_EQUALS_RULE, stack); - } - throw new IllegalArgumentException("Invalid rule: " + symbol); - } -} diff --git a/src/main/java/org/apache/log4j/rule/TimestampEqualsRule.java b/src/main/java/org/apache/log4j/rule/TimestampEqualsRule.java deleted file mode 100644 index 100a8f46d7..0000000000 --- a/src/main/java/org/apache/log4j/rule/TimestampEqualsRule.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import java.io.IOException; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; - -import org.apache.log4j.helpers.Constants; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.LoggingEventFieldResolver; - -/** - * A Rule class implementing equality evaluation for timestamps. - * - * @author Scott Deboy (sdeboy@apache.org) - */ -public class TimestampEqualsRule extends AbstractRule { - /** - * Serialization ID. - */ - static final long serialVersionUID = 1639079557187790321L; - /** - * Resolver. - */ - private static final LoggingEventFieldResolver RESOLVER = - LoggingEventFieldResolver.getInstance(); - /** - * Date format. - */ - private static final DateFormat DATE_FORMAT = - new SimpleDateFormat(Constants.TIMESTAMP_RULE_FORMAT); - - /** - * time stamp. - */ - private long timeStamp; - - /** - * Create new instance. - * @param value string representation of date. - */ - private TimestampEqualsRule(final String value) { - super(); - //expects value to be a timestamp value represented as a long - try { - timeStamp = DATE_FORMAT.parse(value).getTime(); - } catch (ParseException pe) { - throw new IllegalArgumentException("Could not parse date: " + value); - } - } - - /** - * Create new instance. - * @param value string representation of date. - * @return new instance - */ - public static Rule getRule(final String value) { - return new TimestampEqualsRule(value); - } - - /** {@inheritDoc} */ - public boolean evaluate(final LoggingEvent event) { - long eventTimeStamp = Long.parseLong( - RESOLVER.getValue("TIMESTAMP", event).toString()) / 1000 * 1000; - return eventTimeStamp == timeStamp; - } - - /** - * Deserialize the state of the object. - * - * @param in object input stream - * - * @throws IOException if IO error during deserialization - * @throws ClassNotFoundException if class not found during - * deserialization - */ - private void readObject(final java.io.ObjectInputStream in) - throws IOException, ClassNotFoundException { - timeStamp = in.readLong(); - } - - /** - * Serialize the state of the object. - * - * @param out object output stream - * - * @throws IOException if IO error during serialization - */ - private void writeObject(final java.io.ObjectOutputStream out) - throws IOException { - out.writeLong(timeStamp); - } -} diff --git a/src/main/java/org/apache/log4j/rule/TimestampInequalityRule.java b/src/main/java/org/apache/log4j/rule/TimestampInequalityRule.java deleted file mode 100644 index d49f936fd7..0000000000 --- a/src/main/java/org/apache/log4j/rule/TimestampInequalityRule.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rule; - -import java.io.IOException; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; - -import org.apache.log4j.helpers.Constants; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.LoggingEventFieldResolver; - -/** - * A Rule class implementing inequality evaluation for timestamps. - * - * @author Scott Deboy (sdeboy@apache.org) - */ -public class TimestampInequalityRule extends AbstractRule { - /** - * Serialization ID. - */ - static final long serialVersionUID = -4642641663914789241L; - /** - * Resolver. - */ - private static final LoggingEventFieldResolver RESOLVER = - LoggingEventFieldResolver.getInstance(); - /** - * Date format. - */ - private static final DateFormat DATE_FORMAT = - new SimpleDateFormat(Constants.TIMESTAMP_RULE_FORMAT); - /** - * Inequality symbol. - */ - private transient String inequalitySymbol; - /** - * Timestamp. - */ - private long timeStamp; - - /** - * Create new instance. - * @param inequalitySymbol inequality symbol. - * @param value string representation of date. - */ - private TimestampInequalityRule( - final String inequalitySymbol, final String value) { - super(); - this.inequalitySymbol = inequalitySymbol; - try { - timeStamp = DATE_FORMAT.parse(value).getTime(); - } catch (ParseException pe) { - throw new IllegalArgumentException("Could not parse date: " + value); - } - } - - /** - * Create new instance. - * @param inequalitySymbol inequality symbol - * @param value string representation of date - * @return new instance - */ - public static Rule getRule(final String inequalitySymbol, - final String value) { - return new TimestampInequalityRule(inequalitySymbol, value); - } - - /** {@inheritDoc} */ - public boolean evaluate(final LoggingEvent event) { - long eventTimeStamp = Long.parseLong( - RESOLVER.getValue("TIMESTAMP", event).toString()) / 1000 * 1000; - boolean result = false; - long first = eventTimeStamp; - long second = timeStamp; - - if ("<".equals(inequalitySymbol)) { - result = first < second; - } else if (">".equals(inequalitySymbol)) { - result = first > second; - } else if ("<=".equals(inequalitySymbol)) { - result = first <= second; - } else if (">=".equals(inequalitySymbol)) { - result = first >= second; - } - - return result; - } - - /** - * Deserialize the state of the object. - * - * @param in object input stream - * - * @throws IOException if IO error during deserialization - * @throws ClassNotFoundException if class not found - */ - private void readObject(final java.io.ObjectInputStream in) - throws IOException, ClassNotFoundException { - inequalitySymbol = (String) in.readObject(); - timeStamp = in.readLong(); - } - - /** - * Serialize the state of the object. - * - * @param out object output stream - * - * @throws IOException if IO error during serialization - */ - private void writeObject(final java.io.ObjectOutputStream out) - throws IOException { - out.writeObject(inequalitySymbol); - out.writeLong(timeStamp); - } -} diff --git a/src/main/java/org/apache/log4j/scheduler/Job.java b/src/main/java/org/apache/log4j/scheduler/Job.java deleted file mode 100644 index a0e9be4094..0000000000 --- a/src/main/java/org/apache/log4j/scheduler/Job.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.scheduler; - - -/** - * Job is a very simple interface. It only has a single method {@link #execute} - * which is called by the {@link Scheduler} when a task is ready for execution. - *

    - * It is assumed that the execution context - * are contained within the implementing - * {@link Job} itself. - * - * @author Ceki Gülcü - */ -public interface Job { - /** - * Execute job. - */ - void execute(); -} diff --git a/src/main/java/org/apache/log4j/scheduler/Scheduler.java b/src/main/java/org/apache/log4j/scheduler/Scheduler.java deleted file mode 100644 index 72809f77bf..0000000000 --- a/src/main/java/org/apache/log4j/scheduler/Scheduler.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.scheduler; - -import java.util.List; -import java.util.Vector; - -/** - * A simple but still useful implementation of a Scheduler (in memory only). - *

    - * This implementation will work very well when the number of scheduled job is - * small, say less than 100 jobs. If a larger number of events need to be - * scheduled, than a better adapted data structure for the jobList can give - * improved performance. - * - * @author Ceki - */ -public class Scheduler extends Thread { - - /** - * Job list. - */ - List jobList; - /** - * If set true, scheduler has or should shut down. - */ - boolean shutdown = false; - - /** - * Create new instance. - */ - public Scheduler() { - super(); - jobList = new Vector(); - } - - /** - * Find the index of a given job. - * @param job job - * @return -1 if the job could not be found. - */ - int findIndex(final Job job) { - int size = jobList.size(); - boolean found = false; - - int i = 0; - for (; i < size; i++) { - ScheduledJobEntry se = (ScheduledJobEntry) jobList.get(i); - if (se.job == job) { - found = true; - break; - } - } - if (found) { - return i; - } else { - return -1; - } - } - - /** - * Delete the given job. - * @param job job. - * @return true if the job could be deleted, and - * false if the job could not be found or if the Scheduler is about to - * shutdown in which case deletions are not permitted. - */ - public synchronized boolean delete(final Job job) { - // if already shutdown in the process of shutdown, there is no - // need to remove Jobs as they will never be executed. - if (shutdown) { - return false; - } - int i = findIndex(job); - if (i != -1) { - ScheduledJobEntry se = (ScheduledJobEntry) jobList.remove(i); - if (se.job != job) { // this should never happen - new IllegalStateException("Internal programming error"); - } - // if the job is the first on the list, - // then notify the scheduler thread to schedule a new job - if (i == 0) { - this.notifyAll(); - } - return true; - } else { - return false; - } - } - - - /** - * Schedule a {@link Job} for execution at system time given by - * the desiredTime parameter. - * @param job job to schedule. - * @param desiredTime desired time of execution. - */ - public synchronized void schedule(final Job job, - final long desiredTime) { - schedule(new ScheduledJobEntry(job, desiredTime)); - } - - /** - * Schedule a {@link Job} for execution at system time given by - * the desiredTime parameter. - *

    - * The job will be rescheduled. It will execute with a frequency determined - * by the period parameter. - * @param job job to schedule. - * @param desiredTime desired time of execution. - * @param period repeat period. - */ - public synchronized void schedule(final Job job, - final long desiredTime, - final long period) { - schedule(new ScheduledJobEntry(job, desiredTime, period)); - } - - /** - * Change the period of a job. The original job must exist for its period - * to be changed. - *

    - * The method returns true if the period could be changed, and false - * otherwise. - * @param job job. - * @param newPeriod new repeat period. - * @return true if period could be changed. - */ - public synchronized boolean changePeriod(final Job job, - final long newPeriod) { - if (newPeriod <= 0) { - throw new IllegalArgumentException( - "Period must be an integer langer than zero"); - } - - int i = findIndex(job); - if (i == -1) { - return false; - } else { - ScheduledJobEntry se = (ScheduledJobEntry) jobList.get(i); - se.period = newPeriod; - return true; - } - } - - /** - * Schedule a job. - * @param newSJE new job entry. - */ - private synchronized void schedule(final ScheduledJobEntry newSJE) { - // disallow new jobs after shutdown - if (shutdown) { - return; - } - int max = jobList.size(); - long desiredExecutionTime = newSJE.desiredExecutionTime; - - // find the index i such that timeInMillis < jobList[i] - int i = 0; - for (; i < max; i++) { - - ScheduledJobEntry sje = (ScheduledJobEntry) jobList.get(i); - - if (desiredExecutionTime < sje.desiredExecutionTime) { - break; - } - } - jobList.add(i, newSJE); - // if the jobList was empty, then notify the scheduler thread - if (i == 0) { - this.notifyAll(); - } - } - - /** - * Shut down scheduler. - */ - public synchronized void shutdown() { - shutdown = true; - } - - /** - * Run scheduler. - */ - public synchronized void run() { - while (!shutdown) { - if (jobList.isEmpty()) { - linger(); - } else { - ScheduledJobEntry sje = (ScheduledJobEntry) jobList.get(0); - long now = System.currentTimeMillis(); - if (now >= sje.desiredExecutionTime) { - executeInABox(sje.job); - jobList.remove(0); - if (sje.period > 0) { - sje.desiredExecutionTime = now + sje.period; - schedule(sje); - } - } else { - linger(sje.desiredExecutionTime - now); - } - } - } - // clear out the job list to facilitate garbage collection - jobList.clear(); - jobList = null; - System.out.println("Leaving scheduler run method"); - } - - /** - * We do not want a single failure to affect the whole scheduler. - * @param job job to execute. - */ - void executeInABox(final Job job) { - try { - job.execute(); - } catch (Exception e) { - System.err.println("The execution of the job threw an exception"); - e.printStackTrace(System.err); - } - } - - /** - * Wait for notification. - */ - void linger() { - try { - while (jobList.isEmpty() && !shutdown) { - this.wait(); - } - } catch (InterruptedException ie) { - shutdown = true; - } - } - - /** - * Wait for notification or time to elapse. - * @param timeToLinger time to linger. - */ - void linger(final long timeToLinger) { - try { - this.wait(timeToLinger); - } catch (InterruptedException ie) { - shutdown = true; - } - } - - /** - * Represents an entry in job scheduler. - */ - static final class ScheduledJobEntry { - /** - * Desired execution time. - */ - long desiredExecutionTime; - /** - * Job to run. - */ - Job job; - /** - * Repeat period. - */ - long period = 0; - - /** - * Create new instance. - * @param job job - * @param desiredTime desired time. - */ - ScheduledJobEntry(final Job job, final long desiredTime) { - this(job, desiredTime, 0); - } - - /** - * Create new instance. - * @param job job - * @param desiredTime desired time - * @param period repeat period - */ - ScheduledJobEntry(final Job job, - final long desiredTime, - final long period) { - super(); - this.desiredExecutionTime = desiredTime; - this.job = job; - this.period = period; - } - } - -} - - diff --git a/src/main/java/org/apache/log4j/selector/ContextJNDISelector.java b/src/main/java/org/apache/log4j/selector/ContextJNDISelector.java deleted file mode 100644 index 8c5bb8c020..0000000000 --- a/src/main/java/org/apache/log4j/selector/ContextJNDISelector.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.selector; - -import org.apache.log4j.Hierarchy; -import org.apache.log4j.Level; -import org.apache.log4j.LogManager; -import org.apache.log4j.helpers.Constants; -import org.apache.log4j.helpers.IntializationUtil; -import org.apache.log4j.helpers.JNDIUtil; - -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.RepositorySelector; -import org.apache.log4j.spi.RootLogger; - - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import javax.naming.Context; -import javax.naming.NamingException; - - -/** - * Defines a unique logger repository for each web-application in a J2EE environment. - * - * This implementation is

    based primarily on Ceki Gülcü's article

    Supporting the Log4j - * RepositorySelector in Servlet Containers

    at: - * http://qos.ch/logging/sc.html

    - * - *

    By default, the class static RepositorySelector variable - * of the LogManager class is set to a trivial - * {@link org.apache.log4j.spi.RepositorySelector RepositorySelector} - * implementation which always returns the same logger repository. a.k.a. - * hierarchy. In other words, by default log4j will use one hierarchy, the - * default hierarchy. This behavior can be overridden via - * the LogManager's - * setRepositorySelector(RepositorySelector, Object) method.

    - * - *

    That is where this class enters the picture. It can be used to define a - * custom logger repository. It makes use of the fact that in J2EE - * environments, each web-application is guaranteed to have its own JNDI - * context relative to the java:comp/env context. In EJBs, each - * enterprise bean (albeit not each application) has its own context relative - * to the java:comp/env context. An env-entry in a - * deployment descriptor provides the information to the JNDI context. Once the - * env-entry is set, a repository selector can query the JNDI - * application context to look up the value of the entry. The logging context of - * the web-application will depend on the value the env-entry. The JNDI context - * which is looked up by this class is - * java:comp/env/log4j/context-name. - * - *

    Here is an example of an env-entry: - *

    - *
    - * <env-entry>
    - *   <description>JNDI logging context name for this app</description>
    - *   <env-entry-name>log4j/context-name</env-entry-name>
    - *   <env-entry-value>aDistinctiveLoggingContextName</env-entry-value>
    - *   <env-entry-type>java.lang.String</env-entry-type>
    - * </env-entry>
    - * 
    - *
    - *

    - * - *

    If multiple applications use the same logging context name, then they - * will share the same logging context. - *

    - * - *

    You can also specify the URL for this context's configuration resource. - * This repository selector (ContextJNDISelector) will use this resource - * to automatically configure the log4j repository. - *

    - **
    - *
    - * <env-entry>
    - *   <description>URL for configuring log4j context</description>
    - *   <env-entry-name>log4j/configuration-resource</env-entry-name>
    - *   <env-entry-value>urlOfConfigrationResource</env-entry-value>
    - *   <env-entry-type>java.lang.String</env-entry-type>
    - * </env-entry>
    - * 
    - *
    - * - *

    It usually good practice for configuration resources of distinct - * applications to have distinct names. However, if this is not possible - * Naming - * - *

    Note that in case no configuration resource is specified, then there will - * be NO attempt to search for the default configuration files - * log4j.xml and log4j.properties. This voluntary omission - * ensures that the configuration file for your application's logger repository - * will not be confused with the default configuration file for the default - * logger repository. - *

    -* - *

    Given that JNDI is part of the J2EE specification, the JNDI selector - * is the recommended context selector. - *

    - * - * @author Jacob Kjome - * @author Ceki Gülcü - * @since 1.3 - */ -public class ContextJNDISelector implements RepositorySelector { - - static String JNDI_CONFIGURATION_RESOURCE = - "java:comp/env/log4j/configuration-resource"; - static String JNDI_CONFIGURATOR_CLASS = - "java:comp/env/log4j/configurator-class"; - - /** - * key: name of logging context, - * value: Hierarchy instance - */ - private final Map hierMap; - - /** - * public no-args constructor - */ - public ContextJNDISelector() { - hierMap = Collections.synchronizedMap(new HashMap()); - } - - /** - * Return the repoistory selector based on the current JNDI environment. - * - * If the respository is retreived for the first time, then also configure - * the repository using a user specified resource. - * - * @return the appropriate JNDI-keyed context name/LoggerRepository - */ - public LoggerRepository getLoggerRepository() { - String loggingContextName = null; - Context ctx = null; - - try { - ctx = JNDIUtil.getInitialContext(); - loggingContextName = (String) JNDIUtil.lookup(ctx, Constants.JNDI_CONTEXT_NAME); - } catch (NamingException ne) { - // we can't log here - } - - if (loggingContextName == null || Constants.DEFAULT_REPOSITORY_NAME.equals(loggingContextName)) { - return LogManager.defaultLoggerRepository; - } else { - //System.out.println("loggingContextName is ["+loggingContextName+"]"); - Hierarchy hierarchy = (Hierarchy) hierMap.get(loggingContextName); - - if (hierarchy == null) { - // create new hierarchy - hierarchy = new Hierarchy(new RootLogger(Level.DEBUG)); - hierarchy.setName(loggingContextName); - hierMap.put(loggingContextName, hierarchy); - - // configure log4j internal logging - IntializationUtil.log4jInternalConfiguration(hierarchy); - - // Check if Mrs. Piggy gave us explicit configration directives - // regarding this directory. - String configResourceStr = JNDIUtil.lookup(ctx, JNDI_CONFIGURATION_RESOURCE); - - // For non-default repositories we do not try to search for default - // config files such as log4j.xml or log4j.properties because - // we have no deterministic way of finding the right one - if(configResourceStr != null) { - String configuratorClassName = JNDIUtil.lookup(ctx, JNDI_CONFIGURATOR_CLASS); - IntializationUtil.initialConfiguration( - hierarchy, configResourceStr, configuratorClassName); - } - } - - return hierarchy; - } - } - - /** - * Get the logger repository with the corresponding name. - * - *

    Returned value can be null if the selector is unaware of the repository - * with the given name. - */ - public LoggerRepository getLoggerRepository(String name) { - if(Constants.DEFAULT_REPOSITORY_NAME.equals(name)) { - return LogManager.defaultLoggerRepository; - } else { - return (LoggerRepository) hierMap.get(name); - } - } - /** - * Remove the repository with the given name from the list of known - * repositories. - * - * @return the detached repository - */ - public LoggerRepository detachRepository(String contextName) { - return (LoggerRepository) hierMap.remove(contextName); - } -} diff --git a/src/main/java/org/apache/log4j/selector/package.html b/src/main/java/org/apache/log4j/selector/package.html deleted file mode 100644 index 8afdc7f4a8..0000000000 --- a/src/main/java/org/apache/log4j/selector/package.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - org.apache.log4j.selector package - - - - This package contains classes useful for working with Log4j in a container - environment where many applications need to share Log4j without stepping - on each other's logging configuration. -

    Each of these classes implements - the RepositorySelector interface. Only one class may be used - per instance of Log4j. The container normally sets the repository selector, - but one may assign the selector themselves using the InitContextListener in - the org.apache.log4j.serlvet package as well.

    - - diff --git a/src/main/java/org/apache/log4j/selector/servlet/ContextDetachingSCL.java b/src/main/java/org/apache/log4j/selector/servlet/ContextDetachingSCL.java deleted file mode 100644 index f48670dee4..0000000000 --- a/src/main/java/org/apache/log4j/selector/servlet/ContextDetachingSCL.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.selector.servlet; - -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.helpers.Constants; -import org.apache.log4j.helpers.JNDIUtil; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggerRepositoryEx; -import org.apache.log4j.spi.RepositorySelector; -import org.apache.log4j.spi.RepositorySelectorEx; - -import javax.naming.Context; -import javax.naming.NamingException; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -// WARNING -// WARNING Since ServletContextListener gets instantiated by the application -// WARNING server, we have no way of passing it a LoggerRepository instance. -// WARNING It follows that this class should not log except when an LR instance -// WARNING is available. - -/** - * This is a very simple ServletContextListener which detaches a - * {@link LoggerRepository} from {@link ContextJNDISlector} when the - * web-application is destroyed. - * - *

    This class is highly coupled with JNDI but not necessarily - * ContextJNDISlector. - * - * @author Ceki Gülcü - * @since 1.3 - */ -public class ContextDetachingSCL implements ServletContextListener { - - - /** - * When the context is destroy, detach the logging repository given by - * the value of "log4j/context-name" environment variable. - * - * If found, the logging repository is also shutdown. - */ - public void contextDestroyed(ServletContextEvent sce) { - String loggingContextName = null; - - try { - Context ctx = JNDIUtil.getInitialContext(); - loggingContextName = - (String) JNDIUtil.lookup(ctx, Constants.JNDI_CONTEXT_NAME); - } catch (NamingException ne) { - } - - if (loggingContextName != null) { - - System.out.println( - "About to detach logger context named [" + loggingContextName + "]."); - - RepositorySelector repositorySelector = - LogManager.getRepositorySelector(); - if (repositorySelector instanceof RepositorySelectorEx) { - LoggerRepository lr = - ((RepositorySelectorEx) repositorySelector).detachRepository(loggingContextName); - if(lr != null) { - Logger logger = lr.getLogger(this.getClass().getName()); - if (lr instanceof LoggerRepositoryEx) { - logger.debug("About to shutdown logger repository named [{}]", - ((LoggerRepositoryEx) lr).getName()); - } else { - logger.debug("About to shutdown unnamed logger repository"); - } - lr.shutdown(); - } - } - } - } - - /** - * Does nothing. - */ - public void contextInitialized(ServletContextEvent sce) { - } -} diff --git a/src/main/java/org/apache/log4j/spi/AppenderAttachable.java b/src/main/java/org/apache/log4j/spi/AppenderAttachable.java index 8b612f3233..89d7ef4209 100644 --- a/src/main/java/org/apache/log4j/spi/AppenderAttachable.java +++ b/src/main/java/org/apache/log4j/spi/AppenderAttachable.java @@ -18,50 +18,58 @@ package org.apache.log4j.spi; import org.apache.log4j.Appender; - import java.util.Enumeration; - /** Interface for attaching appenders to objects. @author Ceki Gülcü @since 0.9.1 */ public interface AppenderAttachable { + /** Add an appender. */ - public void addAppender(Appender newAppender); + public + void addAppender(Appender newAppender); /** Get all previously added appenders as an Enumeration. */ - public Enumeration getAllAppenders(); + public + Enumeration getAllAppenders(); /** Get an appender by name. */ - public Appender getAppender(String name); + public + Appender getAppender(String name); + /** Returns true if the specified appender is in list of attached attached, false otherwise. @since 1.2 */ - public boolean isAttached(Appender appender); + public + boolean isAttached(Appender appender); /** Remove all previously added appenders. */ void removeAllAppenders(); + /** Remove the appender passed as parameter from the list of appenders. */ - void removeAppender(Appender appender); + void removeAppender(Appender appender); - /** - Remove the appender with the name passed as parameter from the - list of appenders. - */ - void removeAppender(String name); + + /** + Remove the appender with the name passed as parameter from the + list of appenders. + */ + void + removeAppender(String name); } + diff --git a/src/main/java/org/apache/log4j/spi/Component.java b/src/main/java/org/apache/log4j/spi/Component.java deleted file mode 100644 index 28a39b4f2b..0000000000 --- a/src/main/java/org/apache/log4j/spi/Component.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.spi; - - -/** - * A common interface shared by log4j components. - * - * @author Ceki Gulcu - * @since 1.3 - */ -public interface Component { - - - /** - * Set owning logger repository for this component. This operation can - * only be performed once. - * Once set, a subsequent attempt will throw an IllegalStateException. - * - * @param repository The repository where this appender is attached. - */ - void setLoggerRepository(LoggerRepository repository); - -} diff --git a/src/main/java/org/apache/log4j/spi/ComponentBase.java b/src/main/java/org/apache/log4j/spi/ComponentBase.java deleted file mode 100644 index 7f321836cc..0000000000 --- a/src/main/java/org/apache/log4j/spi/ComponentBase.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.spi; - -import org.apache.log4j.ULogger; - - -/** - * Most log4j components derive from this class. - * - * @author Ceki Gulcu - * @since 1.3 - */ -public class ComponentBase implements Component { - - /** - * Error count limit. - */ - private static final int ERROR_COUNT_LIMIT = 3; - - /** - * Logger repository. - */ - protected LoggerRepository repository; - /** - * Logger. - */ - private ULogger logger; - /** - * Error count. - */ - private int errorCount = 0; - - /** - * Construct a new instance. - */ - protected ComponentBase() { - super(); - } - - - /** - * Called by derived classes when they deem that the component has recovered - * from an erroneous state. - */ - protected void resetErrorCount() { - errorCount = 0; - } - - /** - * Set the owning repository. The owning repository cannot be set more than - * once. - * - * @param repository repository - */ - public void setLoggerRepository(final LoggerRepository repository) { - if (this.repository == null) { - this.repository = repository; - } else if (this.repository != repository) { - throw new IllegalStateException("Repository has been already set"); - } - } - - /** - * Return the {@link LoggerRepository} this component is attached to. - * - * @return Owning LoggerRepository - */ - protected LoggerRepository getLoggerRepository() { - return repository; - } - - /** - * Return an instance specific logger to be used by the component itself. - * This logger is not intended to be accessed by the end-user, hence the - * protected keyword. - *

    - *

    In case the repository for this component is not set, - * this implementations returns a {@link SimpleULogger} instance. - * - * @return A ULogger instance. - */ - protected ULogger getLogger() { - if (logger == null) { - if (repository != null) { - logger = repository.getLogger(this.getClass().getName()); - } else { - logger = SimpleULogger.getLogger(this.getClass().getName()); - } - } - return logger; - } - - /** - * Frequently called methods in log4j components can invoke this method in - * order to avoid flooding the output when logging lasting error conditions. - * - * @return a regular logger, or a NOPLogger if called too frequently. - */ - protected ULogger getNonFloodingLogger() { - if (errorCount++ >= ERROR_COUNT_LIMIT) { - return NOPULogger.NOP_LOGGER; - } else { - return getLogger(); - } - } -} diff --git a/src/main/java/org/apache/log4j/spi/Configurator.java b/src/main/java/org/apache/log4j/spi/Configurator.java index 747e836517..75c84b3726 100644 --- a/src/main/java/org/apache/log4j/spi/Configurator.java +++ b/src/main/java/org/apache/log4j/spi/Configurator.java @@ -17,19 +17,17 @@ package org.apache.log4j.spi; -import org.apache.log4j.spi.LoggerRepository; - import java.io.InputStream; import java.net.URL; - /** Implemented by classes capable of configuring log4j using a URL. - + @since 1.0 @author Anders Kristensen */ public interface Configurator { + /** Special level value signifying inherited behaviour. The current value of this string constant is inherited. {@link #NULL} @@ -42,6 +40,21 @@ public interface Configurator { null. */ public static final String NULL = "null"; + + + /** + Interpret a resource pointed by a InputStream and set up log4j accordingly. + + The configuration is done relative to the hierarchy + parameter. + + @param inputStream The InputStream to parse + @param repository The hierarchy to operation upon. + + @since 1.2.17 + */ + void doConfigure(InputStream inputStream, LoggerRepository repository); + /** Interpret a resource pointed by a URL and set up log4j accordingly. @@ -49,7 +62,7 @@ public interface Configurator { parameter. @param url The URL to parse - @param repository The repository to operate upon. + @param repository The hierarchy to operation upon. */ void doConfigure(URL url, LoggerRepository repository); } diff --git a/src/main/java/org/apache/log4j/spi/ConfiguratorEx.java b/src/main/java/org/apache/log4j/spi/ConfiguratorEx.java deleted file mode 100755 index cbbe13ba4f..0000000000 --- a/src/main/java/org/apache/log4j/spi/ConfiguratorEx.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.apache.log4j.spi; - -import java.io.InputStream; - -/** - * Defines extended methods for Configurators to implement. - * - * @author Mark Womack - * @since 1.3 - */ -public interface ConfiguratorEx { - /** - * Configures using an InputStream for input. - * - * @param stream - * @param repository - */ - public void doConfigure(InputStream stream, LoggerRepository repository); -} diff --git a/src/main/java/org/apache/log4j/spi/Decoder.java b/src/main/java/org/apache/log4j/spi/Decoder.java deleted file mode 100644 index fc60e874aa..0000000000 --- a/src/main/java/org/apache/log4j/spi/Decoder.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.spi; - - -import java.io.IOException; - -import java.net.URL; - -import java.util.Map; -import java.util.Vector; - - -/** - * Allow LoggingEvents to be reconstructed from a different format - * (usually XML). - * - * @author Scott Deboy (sdeboy@apache.org) - * @since 1.3 - */ -public interface Decoder { - /** - * Decode events from document. - * @param document document to decode. - * @return list of LoggingEvent instances. - */ - Vector decodeEvents(String document); - - /** - * Decode event from string. - * @param event string representation of event - * @return event - */ - LoggingEvent decode(String event); - - /** - * Decode event from document retreived from URL. - * @param url url of document - * @return list of LoggingEvent instances. - * @throws IOException if IO error resolving document. - */ - Vector decode(URL url) throws IOException; - - /** - * Sets additional properties. - * @param additionalProperties map of additional properties. - */ - void setAdditionalProperties(Map additionalProperties); -} diff --git a/src/main/java/org/apache/log4j/spi/DefaultRepositorySelector.java b/src/main/java/org/apache/log4j/spi/DefaultRepositorySelector.java index 501f0b7c2d..4b307524e4 100644 --- a/src/main/java/org/apache/log4j/spi/DefaultRepositorySelector.java +++ b/src/main/java/org/apache/log4j/spi/DefaultRepositorySelector.java @@ -15,37 +15,23 @@ * limitations under the License. */ + + package org.apache.log4j.spi; -/** - * Trivial implementation of RepositorySelectorEx which takes - * a fixed repository. - */ -public class DefaultRepositorySelector implements RepositorySelectorEx { - - private LoggerRepository defaultRepository; - - /** - * Constructs a new instance. - * @param repository cannot be null - */ - public DefaultRepositorySelector(final LoggerRepository repository) { - if (repository == null) - throw new NullPointerException(); - this.defaultRepository = repository; - } - public LoggerRepository getLoggerRepository() { - return defaultRepository; +public class DefaultRepositorySelector implements RepositorySelector { + + final LoggerRepository repository; + + public + DefaultRepositorySelector(LoggerRepository repository) { + this.repository = repository; } - - /** - * Does nothing, always returns null. - * - * @return Always null - */ - public LoggerRepository detachRepository(final String name) { - // do nothing, as the default repository cannot be removed - return null; + + public + LoggerRepository getLoggerRepository() { + return repository; } } + diff --git a/src/main/java/org/apache/log4j/spi/ErrorHandler.java b/src/main/java/org/apache/log4j/spi/ErrorHandler.java index 510fd04d05..d629a2dbd2 100644 --- a/src/main/java/org/apache/log4j/spi/ErrorHandler.java +++ b/src/main/java/org/apache/log4j/spi/ErrorHandler.java @@ -22,24 +22,71 @@ /** - ErrorHandler and its implementations are no longer - utilized by Log4j. The ErrorHandler interface and any - implementations of it are only here to provide binary runtime - compatibility with versions previous to 1.3, most specifically - 1.2.xx versions. + Appenders may delegate their error handling to + ErrorHandlers. + +

    Error handling is a particularly tedious to get right because by + definition errors are hard to predict and to reproduce. + + +

    Please take the time to contact the author in case you discover + that errors are not properly handled. You are most welcome to + suggest new error handling policies or criticize existing policies. + @author Ceki Gülcü - @deprecated As of 1.3 - */ + +*/ public interface ErrorHandler extends OptionHandler { - /**@since 1.2*/ + + /** + Add a reference to a logger to which the failing appender might + be attached to. The failing appender will be searched and + replaced only in the loggers you add through this method. + + @param logger One of the loggers that will be searched for the failing + appender in view of replacement. + + @since 1.2 */ void setLogger(Logger logger); + + + /** + Equivalent to the {@link #error(String, Exception, int, + LoggingEvent event)} with the the event parameteter set to + null. + + */ void error(String message, Exception e, int errorCode); + + /** + This method is normally used to just print the error message + passed as a parameter. + */ void error(String message); - /**@since 1.2*/ + + /** + This method is invoked to handle the error. + + @param message The message assoicated with the error. + @param e The Exption that was thrown when the error occured. + @param errorCode The error code associated with the error. + @param event The logging event that the failing appender is asked + to log. + + @since 1.2 */ void error(String message, Exception e, int errorCode, LoggingEvent event); - /**@since 1.2*/ + + /** + Set the appender for which errors are handled. This method is + usually called when the error handler is configured. + + @since 1.2 */ void setAppender(Appender appender); - /**@since 1.2*/ + + /** + Set the appender to falkback upon in case of failure. + + @since 1.2 */ void setBackupAppender(Appender appender); } diff --git a/src/main/java/org/apache/log4j/spi/ErrorItem.java b/src/main/java/org/apache/log4j/spi/ErrorItem.java deleted file mode 100644 index f6f36863bc..0000000000 --- a/src/main/java/org/apache/log4j/spi/ErrorItem.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.spi; - -import java.io.PrintStream; - -/** - * Used to store special log4j errors which cannot be logged using internal - * logging. Such errors include those occurring during the initial phases - * of log4j configuration or errors emanating from core components such as - * Logger or Hierarchy. - * - * @author Ceki Gulcu - */ -public class ErrorItem { - /** - * Message. - */ - String message; - /** - * Column. - */ - int colNumber = -1; - /** - * Line number. - */ - int lineNumber = -1; - /** - * Exception. - */ - Throwable exception; - - /** - * Create new instance. - * @param message message - * @param e exception - */ - public ErrorItem(final String message, final Exception e) { - super(); - this.message = message; - exception = e; - } - - /** - * Creaet new instance. - * @param message message. - */ - public ErrorItem(final String message) { - this(message, null); - } - - /** - * Get column number. - * @return column number. - */ - public int getColNumber() { - return colNumber; - } - - /** - * Set column number. - * @param colNumber new column number. - */ - public void setColNumber(int colNumber) { - this.colNumber = colNumber; - } - - /** - * Get exception. - * @return exception. - */ - public Throwable getException() { - return exception; - } - - /** - * Set exception. - * @param exception exception - */ - public void setException(final Throwable exception) { - this.exception = exception; - } - - /** - * Get line number. - * @return line number. - */ - public int getLineNumber() { - return lineNumber; - } - - /** - * Set line number. - * @param lineNumber line number. - */ - public void setLineNumber(final int lineNumber) { - this.lineNumber = lineNumber; - } - - /** - * Get message. - * @return message. - */ - public String getMessage() { - return message; - } - - /** - * Set message. - * @param message message. - */ - public void setMessage(final String message) { - this.message = message; - } - - /** - * String representation of ErrorItem. - * @return string. - */ - public String toString() { - String str = - "Reported error: \"" + message + "\""; - - if (lineNumber != -1) { - str += " at line " + lineNumber + " column " + colNumber; - } - if (exception != null) { - str += (" with exception " + exception); - } - return str; - } - - /** - * Dump the details of this ErrorItem to System.out. - */ - public void dump() { - dump(System.out); - } - - /** - * Dump the details of this ErrorItem on the specified {@link PrintStream}. - * @param ps print stream. - */ - public void dump(final PrintStream ps) { - String str = - "Reported error: \"" + message + "\""; - - if (lineNumber != -1) { - str += " at line " + lineNumber + " column " + colNumber; - } - ps.println(str); - - if (exception != null) { - exception.printStackTrace(ps); - } - } -} diff --git a/src/main/java/org/apache/log4j/spi/Filter.java b/src/main/java/org/apache/log4j/spi/Filter.java index 6f4b6bdebb..7bddbe828c 100644 --- a/src/main/java/org/apache/log4j/spi/Filter.java +++ b/src/main/java/org/apache/log4j/spi/Filter.java @@ -17,7 +17,6 @@ package org.apache.log4j.spi; -import org.apache.log4j.spi.LoggingEvent; /** @@ -39,7 +38,7 @@

    If the value {@link #DENY} is returned, then the log event is dropped immediately without consulting with the remaining - filters. + filters.

    If the value {@link #NEUTRAL} is returned, then the next filter in the chain is consulted. If there are no more filters in the @@ -47,10 +46,10 @@ filters, the default behaviour is to log all logging events.

    If the value {@link #ACCEPT} is returned, then the log - event is logged without consulting the remaining filters. + event is logged without consulting the remaining filters.

    The philosophy of log4j filters is largely inspired from the - Linux ipchains. + Linux ipchains.

    Note that filtering is only supported by the {@link org.apache.log4j.xml.DOMConfigurator DOMConfigurator}. The {@link @@ -59,12 +58,20 @@ @author Ceki Gülcü @since 0.9.0 */ -public abstract class Filter extends ComponentBase implements OptionHandler { +public abstract class Filter implements OptionHandler { + + /** + Points to the next filter in the filter chain. + + @deprecated As of 1.2.12, use {@link #getNext} and {@link #setNext} instead + */ + public Filter next; + /** The log event must be dropped immediately without consulting with the remaining filters, if any, in the chain. */ - public static final int DENY = -1; - + public static final int DENY = -1; + /** This filter is neutral with respect to the log event. The remaining filters, if any, should be consulted for a final decision. @@ -74,23 +81,20 @@ public abstract class Filter extends ComponentBase implements OptionHandler { /** The log event must be logged immediately without consulting with the remaining filters, if any, in the chain. */ - public static final int ACCEPT = 1; + public static final int ACCEPT = 1; - /** - Points to the next filter in the filter chain. - - @deprecated As of 1.2.12, use {@link #getNext} and {@link #setNext} instead - */ - public Filter next; /** Usually filters options become active when set. We provide a default do-nothing implementation for convenience. */ - public void activateOptions() { + public + void activateOptions() { } - /** + + + /**

    If the decision is DENY, then the event will be dropped. If the decision is NEUTRAL, then the next filter, if any, will be invoked. If the decision is ACCEPT then @@ -98,9 +102,11 @@ public void activateOptions() { the chain. @param event The LoggingEvent to decide upon. - */ - public abstract int decide(LoggingEvent event); - + @return decision The decision of the filter. */ + abstract + public + int decide(LoggingEvent event); + /** * Set the next filter pointer. */ diff --git a/src/main/java/org/apache/log4j/spi/HierarchyEventListener.java b/src/main/java/org/apache/log4j/spi/HierarchyEventListener.java index 5625f8bec1..77a0efda1d 100644 --- a/src/main/java/org/apache/log4j/spi/HierarchyEventListener.java +++ b/src/main/java/org/apache/log4j/spi/HierarchyEventListener.java @@ -20,20 +20,26 @@ import org.apache.log4j.Appender; import org.apache.log4j.Category; - /** Listen to events occuring within a {@link org.apache.log4j.Hierarchy Hierarchy}. @author Ceki Gülcü @since 1.2 - @deprecated Superceded by LoggerEventListener. - + */ public interface HierarchyEventListener { + + //public //void categoryCreationEvent(Category cat); - public void addAppenderEvent(Category cat, Appender appender); - public void removeAppenderEvent(Category cat, Appender appender); + + public + void addAppenderEvent(Category cat, Appender appender); + + public + void removeAppenderEvent(Category cat, Appender appender); + + } diff --git a/src/main/java/org/apache/log4j/spi/HierarchyEventListenerAdapter.java b/src/main/java/org/apache/log4j/spi/HierarchyEventListenerAdapter.java deleted file mode 100644 index 379ef75e56..0000000000 --- a/src/main/java/org/apache/log4j/spi/HierarchyEventListenerAdapter.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.spi; - -import org.apache.log4j.Appender; -import org.apache.log4j.Logger; - - -/** - * Adapter class that wraps an object that implements - * HierarchyEventListener and exposes the log4j 1.3 introduced - * LoggerEventListener interface. - * - * @deprecated - */ -public final class HierarchyEventListenerAdapter implements LoggerEventListener { - /** - * Wrapped listener. - */ - private final org.apache.log4j.spi.HierarchyEventListener listener; - - /** - * Constructs a new instance of HierarchyEventListenerAdapter. - * @param listener - * @deprecated - */ - public HierarchyEventListenerAdapter( - final org.apache.log4j.spi.HierarchyEventListener listener) { - if (listener == null) { - throw new IllegalArgumentException("listener"); - } - - this.listener = listener; - } - - /** - Called when an appender is added to the logger. - - @param logger The logger to which the appender was added. - @param appender The appender added to the logger. */ - public void appenderAddedEvent(final Logger logger, final Appender appender) { - listener.addAppenderEvent(logger, appender); - } - - /** - Called when an appender is removed from the logger. - - @param logger The logger from which the appender was removed. - @param appender The appender removed from the logger. */ - public void appenderRemovedEvent( - final Logger logger, final Appender appender) { - listener.removeAppenderEvent(logger, appender); - } - - /** - Called when level changed on the logger. - - @param logger The logger that changed levels. */ - public void levelChangedEvent(final Logger logger) { - } -} diff --git a/src/main/java/org/apache/log4j/spi/LocationInfo.java b/src/main/java/org/apache/log4j/spi/LocationInfo.java index 57b2f29c33..2da5486008 100644 --- a/src/main/java/org/apache/log4j/spi/LocationInfo.java +++ b/src/main/java/org/apache/log4j/spi/LocationInfo.java @@ -15,13 +15,18 @@ * limitations under the License. */ - // Contributors: Mathias Rupprecht + package org.apache.log4j.spi; -import org.apache.log4j.helpers.PlatformInfo; -import org.apache.log4j.spi.location.LegacyExtractor; -import org.apache.log4j.spi.location.StackTraceElementExtractor; +import org.apache.log4j.Layout; +import org.apache.log4j.helpers.LogLog; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.InterruptedIOException; +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; /** The internal representation of caller location information. @@ -30,58 +35,79 @@ */ public class LocationInfo implements java.io.Serializable { - /** - When location information is not available the constant - NA is returned. Current value of this string - constant is ?. */ - public static final String NA = "?"; - - static final long serialVersionUID = -1325822038990805636L; - - /** - * NA_LOCATION_INFO is used in conjunction with deserialized LoggingEvents - * without real location info available. - * @since 1.3 - */ - public static final LocationInfo NA_LOCATION_INFO = new LocationInfo(NA, NA, NA, NA); - - - /** Caller's line number. */ - public String lineNumber; - + transient String lineNumber; /** Caller's file name. */ - public String fileName; - + transient String fileName; /** Caller's fully qualified class name. */ - public String className; - + transient String className; /** Caller's method name. */ - public String methodName; - + transient String methodName; /** All available caller information, in the format fully.qualified.classname.of.caller.methodName(Filename.java:line) */ - public transient String fullInfo; - - public LocationInfo( - String fileName, String className, String methodName, String lineNumber) { - this.fileName = fileName; - this.className = className; - this.methodName = methodName; - this.lineNumber = lineNumber; + public String fullInfo; + + private static StringWriter sw = new StringWriter(); + private static PrintWriter pw = new PrintWriter(sw); + + private static Method getStackTraceMethod; + private static Method getClassNameMethod; + private static Method getMethodNameMethod; + private static Method getFileNameMethod; + private static Method getLineNumberMethod; + + + /** + When location information is not available the constant + NA is returned. Current value of this string + constant is ?. */ + public final static String NA = "?"; + + static final long serialVersionUID = -1325822038990805636L; + + /** + * NA_LOCATION_INFO is provided for compatibility with log4j 1.3. + * @since 1.2.15 + */ + public static final LocationInfo NA_LOCATION_INFO = + new LocationInfo(NA, NA, NA, NA); + + + + // Check if we are running in IBM's visual age. + static boolean inVisualAge = false; + static { + try { + inVisualAge = Class.forName("com.ibm.uvm.tools.DebugSupport") != null; + LogLog.debug("Detected IBM VisualAge environment."); + } catch(Throwable e) { + // nothing to do + } + try { + Class[] noArgs = null; + getStackTraceMethod = Throwable.class.getMethod("getStackTrace", noArgs); + Class stackTraceElementClass = Class.forName("java.lang.StackTraceElement"); + getClassNameMethod = stackTraceElementClass.getMethod("getClassName", noArgs); + getMethodNameMethod = stackTraceElementClass.getMethod("getMethodName", noArgs); + getFileNameMethod = stackTraceElementClass.getMethod("getFileName", noArgs); + getLineNumberMethod = stackTraceElementClass.getMethod("getLineNumber", noArgs); + } catch(ClassNotFoundException ex) { + LogLog.debug("LocationInfo will use pre-JDK 1.4 methods to determine location."); + } catch(NoSuchMethodException ex) { + LogLog.debug("LocationInfo will use pre-JDK 1.4 methods to determine location."); + } } - /** Instantiate location information based on a Throwable. We expect the Throwable t, to be in the format @@ -94,113 +120,288 @@ public LocationInfo( at org.apache.log4j.Category.callAppenders(Category.java:131) at org.apache.log4j.Category.log(Category.java:512) at callers.fully.qualified.className.methodName(FileName.java:74) - ... + ...

    However, we can also deal with JIT compilers that "lose" the location information, especially between the parentheses. + @param t throwable used to determine location, may be null. + @param fqnOfCallingClass class name of first class considered part of + the logging framework. Location will be site that calls a method on this class. */ - public LocationInfo(Throwable t, String fqnOfInvokingClass) { - if (t == null) { - return; + public LocationInfo(Throwable t, String fqnOfCallingClass) { + if(t == null || fqnOfCallingClass == null) { + return; } - - if(PlatformInfo.hasStackTraceElement()) { - StackTraceElementExtractor.extract(this, t, fqnOfInvokingClass); - } else { - LegacyExtractor.extract(this, t, fqnOfInvokingClass); + if (getLineNumberMethod != null) { + try { + Object[] noArgs = null; + Object[] elements = (Object[]) getStackTraceMethod.invoke(t, noArgs); + String prevClass = NA; + for(int i = elements.length - 1; i >= 0; i--) { + String thisClass = (String) getClassNameMethod.invoke(elements[i], noArgs); + if(fqnOfCallingClass.equals(thisClass)) { + int caller = i + 1; + if (caller < elements.length) { + className = prevClass; + methodName = (String) getMethodNameMethod.invoke(elements[caller], noArgs); + fileName = (String) getFileNameMethod.invoke(elements[caller], noArgs); + if (fileName == null) { + fileName = NA; + } + int line = ((Integer) getLineNumberMethod.invoke(elements[caller], noArgs)).intValue(); + if (line < 0) { + lineNumber = NA; + } else { + lineNumber = String.valueOf(line); + } + StringBuffer buf = new StringBuffer(); + buf.append(className); + buf.append("."); + buf.append(methodName); + buf.append("("); + buf.append(fileName); + buf.append(":"); + buf.append(lineNumber); + buf.append(")"); + this.fullInfo = buf.toString(); + } + return; + } + prevClass = thisClass; + } + return; + } catch(IllegalAccessException ex) { + LogLog.debug("LocationInfo failed using JDK 1.4 methods", ex); + } catch(InvocationTargetException ex) { + if (ex.getTargetException() instanceof InterruptedException + || ex.getTargetException() instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.debug("LocationInfo failed using JDK 1.4 methods", ex); + } catch(RuntimeException ex) { + LogLog.debug("LocationInfo failed using JDK 1.4 methods", ex); + } + } + + String s; + // Protect against multiple access to sw. + synchronized(sw) { + t.printStackTrace(pw); + s = sw.toString(); + sw.getBuffer().setLength(0); + } + //System.out.println("s is ["+s+"]."); + int ibegin, iend; + + // Given the current structure of the package, the line + // containing "org.apache.log4j.Category." should be printed just + // before the caller. + + // This method of searching may not be fastest but it's safer + // than counting the stack depth which is not guaranteed to be + // constant across JVM implementations. + ibegin = s.lastIndexOf(fqnOfCallingClass); + if(ibegin == -1) { + return; } - } - public boolean equals(Object o) { - //LogLog.info("equals called"); - if (this == o) { - return true; + // + // if the next character after the class name exists + // but is not a period, see if the classname is + // followed by a period earlier in the trace. + // Minimizes mistakeningly matching on a class whose + // name is a substring of the desired class. + // See bug 44888. + if (ibegin + fqnOfCallingClass.length() < s.length() && + s.charAt(ibegin + fqnOfCallingClass.length()) != '.') { + int i = s.lastIndexOf(fqnOfCallingClass + "."); + if (i != -1) { + ibegin = i; + } + } + + + ibegin = s.indexOf(Layout.LINE_SEP, ibegin); + if(ibegin == -1) { + return; + } + ibegin+= Layout.LINE_SEP_LEN; + + // determine end of line + iend = s.indexOf(Layout.LINE_SEP, ibegin); + if(iend == -1) { + return; } - if (!(o instanceof LocationInfo)) { - //LogLog.info("inequality point 1"); - return false; + // VA has a different stack trace format which doesn't + // need to skip the inital 'at' + if(!inVisualAge) { + // back up to first blank character + ibegin = s.lastIndexOf("at ", iend); + if(ibegin == -1) { + return; + } + // Add 3 to skip "at "; + ibegin += 3; + } + // everything between is the requested stack item + this.fullInfo = s.substring(ibegin, iend); } - LocationInfo r = (LocationInfo) o; + /** + * Appends a location fragment to a buffer to build the + * full location info. + * @param buf StringBuffer to receive content. + * @param fragment fragment of location (class, method, file, line), + * if null the value of NA will be appended. + * @since 1.2.15 + */ + private static final void appendFragment(final StringBuffer buf, + final String fragment) { + if (fragment == null) { + buf.append(NA); + } else { + buf.append(fragment); + } + } - if(!getClassName().equals(r.getClassName())){ - //LogLog.info("inequality point 2"); - return false; + /** + * Create new instance. + * @param file source file name + * @param classname class name + * @param method method + * @param line source line number + * + * @since 1.2.15 + */ + public LocationInfo( + final String file, + final String classname, + final String method, + final String line) { + this.fileName = file; + this.className = classname; + this.methodName = method; + this.lineNumber = line; + StringBuffer buf = new StringBuffer(); + appendFragment(buf, classname); + buf.append("."); + appendFragment(buf, method); + buf.append("("); + appendFragment(buf, file); + buf.append(":"); + appendFragment(buf, line); + buf.append(")"); + this.fullInfo = buf.toString(); } - - if(!getFileName().equals(r.getFileName())) { - //LogLog.info("inequality point 3"); - return false; + + /** + Return the fully qualified class name of the caller making the + logging request. + */ + public + String getClassName() { + if(fullInfo == null) { + return NA; } + if(className == null) { + // Starting the search from '(' is safer because there is + // potentially a dot between the parentheses. + int iend = fullInfo.lastIndexOf('('); + if(iend == -1) { + className = NA; + } else { + iend =fullInfo.lastIndexOf('.', iend); + + // This is because a stack trace in VisualAge looks like: - if(!getMethodName().equals(r.getMethodName())){ - //LogLog.info("inequality point 4"); - return false; + //java.lang.RuntimeException + // java.lang.Throwable() + // java.lang.Exception() + // java.lang.RuntimeException() + // void test.test.B.print() + // void test.test.A.printIndirect() + // void test.test.Run.main(java.lang.String []) + int ibegin = 0; + if (inVisualAge) { + ibegin = fullInfo.lastIndexOf(' ', iend)+1; + } + + if(iend == -1) { + className = NA; + } else { + className = this.fullInfo.substring(ibegin, iend); } - - if(!getLineNumber().equals(r.getLineNumber())){ - //LogLog.info("inequality point 5"); - return false; + } + } + return className; } - - return true; - } - - public int hashCode() { - return getClassName().hashCode() + getLineNumber().hashCode(); - } - - - /** - Return the fully qualified class name of the caller making the - logging request. - */ - public String getClassName() { - return className; - } + /** + Return the file name of the caller. - /** - Return the file name of the caller. +

    This information is not always available. + */ + public + String getFileName() { + if(fullInfo == null) { + return NA; + } -

    This information is not always available. - */ - public String getFileName() { - return fileName; - } + if(fileName == null) { + int iend = fullInfo.lastIndexOf(':'); + if(iend == -1) { + fileName = NA; + } else { + int ibegin = fullInfo.lastIndexOf('(', iend - 1); + fileName = this.fullInfo.substring(ibegin + 1, iend); + } + } + return fileName; + } - /** - Returns the line number of the caller. + /** + Returns the line number of the caller. -

    This information is not always available. - */ - public String getLineNumber() { - return lineNumber; - } +

    This information is not always available. + */ + public + String getLineNumber() { + if(fullInfo == null) { + return NA; + } - /** - Returns the method name of the caller. - */ - public String getMethodName() { - return methodName; - } - - /** - * fullInfo format is: - * fully.qualified.classname.of.caller.methodName(Filename.java:line) - */ - public String getFullInfo() { - if(fullInfo == null) { - fullInfo = getClassName()+"."+getMethodName()+"("+getFileName()+":"+ - getLineNumber()+")"; - } - return fullInfo; - } - - public String toString() { - return "(class="+getClassName()+", file="+getFileName()+", line="+getLineNumber()+", methodName="+getMethodName(); - } + if(lineNumber == null) { + int iend = fullInfo.lastIndexOf(')'); + int ibegin = fullInfo.lastIndexOf(':', iend -1); + if(ibegin == -1) { + lineNumber = NA; + } else { + lineNumber = this.fullInfo.substring(ibegin + 1, iend); + } + } + return lineNumber; + } + + /** + Returns the method name of the caller. + */ + public + String getMethodName() { + if(fullInfo == null) { + return NA; + } + if(methodName == null) { + int iend = fullInfo.lastIndexOf('('); + int ibegin = fullInfo.lastIndexOf('.', iend); + if(ibegin == -1) { + methodName = NA; + } else { + methodName = this.fullInfo.substring(ibegin + 1, iend); + } + } + return methodName; + } } diff --git a/src/main/java/org/apache/log4j/spi/LoggerEventListener.java b/src/main/java/org/apache/log4j/spi/LoggerEventListener.java deleted file mode 100644 index 274ea8fcc9..0000000000 --- a/src/main/java/org/apache/log4j/spi/LoggerEventListener.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.spi; - -import org.apache.log4j.Appender; -import org.apache.log4j.Logger; - - -/** - Interface used to listen for {@link Logger} related events such as - add/remove appender or changing levels. Clients register an instance of - the interface and the instance is called back when the various events occur. - - {@link LoggerRepository} provides methods for adding and removing - LoggerEventListener instances. - - When implementing the methods of this interface, it is useful to remember - that the Logger can access the repository using its getRepository() - method. - - @author Ceki Gülcü - @author Mark Womack - @since 1.3 -*/ -public interface LoggerEventListener { - /** - Called when an appender is added to the logger. - - @param logger The logger to which the appender was added. - @param appender The appender added to the logger. */ - void appenderAddedEvent(Logger logger, Appender appender); - - /** - Called when an appender is removed from the logger. - - @param logger The logger from which the appender was removed. - @param appender The appender removed from the logger. */ - void appenderRemovedEvent(Logger logger, Appender appender); - - /** - Called when level changed on the logger. - - @param logger The logger that changed levels. */ - void levelChangedEvent(Logger logger); -} diff --git a/src/main/java/org/apache/log4j/spi/LoggerFactory.java b/src/main/java/org/apache/log4j/spi/LoggerFactory.java index d99196b850..568c41fe19 100644 --- a/src/main/java/org/apache/log4j/spi/LoggerFactory.java +++ b/src/main/java/org/apache/log4j/spi/LoggerFactory.java @@ -19,9 +19,8 @@ import org.apache.log4j.Logger; - /** - + Implement this interface to create new instances of Logger or a sub-class of Logger. @@ -29,8 +28,11 @@ @author Ceki Gülcü @since version 0.8.5 - + */ public interface LoggerFactory { - public Logger makeNewLoggerInstance(String name); + + public + Logger makeNewLoggerInstance(String name); + } diff --git a/src/main/java/org/apache/log4j/spi/LoggerRepository.java b/src/main/java/org/apache/log4j/spi/LoggerRepository.java index aacfae497b..9ca156b86a 100644 --- a/src/main/java/org/apache/log4j/spi/LoggerRepository.java +++ b/src/main/java/org/apache/log4j/spi/LoggerRepository.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,14 +17,13 @@ package org.apache.log4j.spi; +import java.util.Enumeration; + import org.apache.log4j.Appender; import org.apache.log4j.Category; import org.apache.log4j.Level; import org.apache.log4j.Logger; -import java.util.Enumeration; - - /** A LoggerRepository is used to create and retrieve Loggers. The relation between loggers in a repository @@ -38,11 +37,12 @@ @author Ceki Gülcü @since 1.2 */ public interface LoggerRepository { + /** Add a {@link HierarchyEventListener} event to the repository. - @deprecated Superceded by LoggerRepositoryEx.addLoggerEventListener. */ - public void addHierarchyEventListener(HierarchyEventListener listener); + public + void addHierarchyEventListener(HierarchyEventListener listener); /** Returns whether this repository is disabled for a given @@ -55,38 +55,56 @@ public interface LoggerRepository { Set the repository-wide threshold. All logging requests below the threshold are immediately dropped. By default, the threshold is set to Level.ALL which has the lowest possible rank. */ - public void setThreshold(Level level); + public + void setThreshold(Level level); /** Another form of {@link #setThreshold(Level)} accepting a string parameter instead of a Level. */ - public void setThreshold(String val); + public + void setThreshold(String val); - public void emitNoAppenderWarning(Category cat); + public + void emitNoAppenderWarning(Category cat); /** Get the repository-wide threshold. See {@link #setThreshold(Level)} for an explanation. */ - public Level getThreshold(); + public + Level getThreshold(); - public Logger getLogger(String name); + public + Logger getLogger(String name); - public Logger getLogger(String name, LoggerFactory factory); + public + Logger getLogger(String name, LoggerFactory factory); - public Logger getRootLogger(); + public + Logger getRootLogger(); - public abstract Logger exists(String name); + public + abstract + Logger exists(String name); - public abstract void shutdown(); + public + abstract + void shutdown(); - public Enumeration getCurrentLoggers(); + public + Enumeration getCurrentLoggers(); /** Deprecated. Please use {@link #getCurrentLoggers} instead. */ - public Enumeration getCurrentCategories(); + public + Enumeration getCurrentCategories(); + + + public + abstract + void fireAddAppenderEvent(Category logger, Appender appender); - public abstract void fireAddAppenderEvent( - Category logger, Appender appender); + public + abstract + void resetConfiguration(); - public abstract void resetConfiguration(); } diff --git a/src/main/java/org/apache/log4j/spi/LoggerRepositoryEventListener.java b/src/main/java/org/apache/log4j/spi/LoggerRepositoryEventListener.java deleted file mode 100644 index 09d4d7872b..0000000000 --- a/src/main/java/org/apache/log4j/spi/LoggerRepositoryEventListener.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.spi; - - -/** - Interface used to listen for {@link LoggerRepository} related - events such as startup, reset, and shutdown. Clients register - an instance of the interface and the instance is called back - when the various events occur. - - {@link LoggerRepository} provides methods for adding and removing - LoggerEventListener instances. - - @author Ceki Gülcü - @author Mark Womack - @since 1.3 -*/ -public interface LoggerRepositoryEventListener { - /** - Called when the repository configuration is reset. - @param repository repository - */ - void configurationResetEvent(LoggerRepository repository); - - /** - Called when the repository configuration is changed. - @param repository repository - */ - void configurationChangedEvent(LoggerRepository repository); - - /** - Called when the repository is shutdown. When this method is - invoked, the repository is still valid (ie it has not been - shutdown, but will be after this method returns). - @param repository repository. - */ - void shutdownEvent(LoggerRepository repository); -} diff --git a/src/main/java/org/apache/log4j/spi/LoggerRepositoryEx.java b/src/main/java/org/apache/log4j/spi/LoggerRepositoryEx.java deleted file mode 100644 index 3374a66e73..0000000000 --- a/src/main/java/org/apache/log4j/spi/LoggerRepositoryEx.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.spi; - -import org.apache.log4j.Appender; -import org.apache.log4j.Category; -import org.apache.log4j.Logger; -import org.apache.log4j.plugins.PluginRegistry; -import org.apache.log4j.scheduler.Scheduler; - -import java.util.List; -import java.util.Map; - - -/** - A LoggerRepository is used to create and retrieve - Loggers. The relation between loggers in a repository - depends on the repository but typically loggers are arranged in a - named hierarchy. - -

    In addition to the creational methods, a - LoggerRepository can be queried for existing loggers, - can act as a point of registry for events related to loggers. - - @author Ceki Gülcü - @author Mark Womack - @author Curt Arnold - @since 1.3 */ -public interface LoggerRepositoryEx extends LoggerRepository { - /** - Add a {@link LoggerRepositoryEventListener} to the repository. The - listener will be called when repository events occur. - @param listener event listener, may not be null. - @since 1.3*/ - void addLoggerRepositoryEventListener( - LoggerRepositoryEventListener listener); - - /** - Remove a {@link LoggerRepositoryEventListener} from the repository. - @param listener listener. - @since 1.3*/ - void removeLoggerRepositoryEventListener( - LoggerRepositoryEventListener listener); - - /** - Add a {@link LoggerEventListener} to the repository. The listener - will be called when repository events occur. - @param listener listener, may not be null. - @since 1.3*/ - void addLoggerEventListener(LoggerEventListener listener); - - /** - Remove a {@link LoggerEventListener} from the repository. - @param listener listener, may not be null. - @since 1.3*/ - void removeLoggerEventListener(LoggerEventListener listener); - - /** - * Get the name of this logger repository. - * @return name, may not be null. - * @since 1.3 - */ - String getName(); - - /** - * A logger repository is a named entity. - * @param repoName new name, may not be null. - * @since 1.3 - */ - void setName(String repoName); - - /** - * Is the current configuration of the repository in its original (pristine) - * state? - * @return true if repository is in original state. - * - * @since 1.3 - */ - boolean isPristine(); - - /** - * Set the pristine flag. - * @param state state - * @see #isPristine - * @since 1.3 - */ - void setPristine(boolean state); - - /** - Requests that a appender removed event be sent to any registered - {@link LoggerEventListener}. - @param logger The logger from which the appender was removed. - @param appender The appender removed from the logger. - @since 1.3*/ - void fireRemoveAppenderEvent(Category logger, Appender appender); - - /** - Requests that a level changed event be sent to any registered - {@link LoggerEventListener}. - @param logger The logger which changed levels. - @since 1.3*/ - void fireLevelChangedEvent(Logger logger); - - /** - Requests that a configuration changed event be sent to any registered - {@link LoggerRepositoryEventListener}. - @since 1.3*/ - void fireConfigurationChangedEvent(); - - /** - * Return the PluginRegisty for this LoggerRepository. - * @return plug in registry. - * @since 1.3 - */ - PluginRegistry getPluginRegistry(); - - /** - * Return the {@link Scheduler} for this LoggerRepository. - * @return scheduler. - * @since 1.3 - */ - Scheduler getScheduler(); - - /** - * Get the properties specific for this repository. - * @return property map. - * @since 1.3 - */ - Map getProperties(); - - /** - * Get the property of this repository. - * @param key property key. - * @return key value or null if not set. - * @since 1.3 - */ - String getProperty(String key); - - /** - * Set a property of this repository. - * @param key key, may not be null. - * @param value new value, if null, property will be removed. - * @since 1.3 - */ - void setProperty(String key, String value); - - /** - * Errors which cannot be logged, go to the error list. - * - * @return List - */ - List getErrorList(); - - /** - * Errors which cannot be logged, go to the error list. - * - * @param errorItem an ErrorItem to add to the error list - */ - void addErrorItem(ErrorItem errorItem); - - /** - * A LoggerRepository can also act as a store for various objects used - * by log4j components. - * - * @param key key, may not be null. - * @return The object stored under 'key'. - * @since 1.3 - */ - Object getObject(String key); - - /** - * Store an object under 'key'. If no object can be found, null is returned. - * - * @param key key, may not be null. - * @param value value, may be null. - */ - void putObject(String key, Object value); - - /** - * Sets the logger factory used by {@link LoggerRepository#getLogger(String)}. - * @param loggerFactory factory to use, may not be null - * @since 1.3 - */ - void setLoggerFactory(LoggerFactory loggerFactory); - - /** - * Returns the logger factory used by - * {@link LoggerRepository#getLogger(String)}. - * - * @return non-null factory - * @since 1.3 - */ - LoggerFactory getLoggerFactory(); - -} diff --git a/src/main/java/org/apache/log4j/spi/LoggingEvent.java b/src/main/java/org/apache/log4j/spi/LoggingEvent.java index 6302431533..0475b671af 100644 --- a/src/main/java/org/apache/log4j/spi/LoggingEvent.java +++ b/src/main/java/org/apache/log4j/spi/LoggingEvent.java @@ -1,261 +1,196 @@ /* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ + package org.apache.log4j.spi; +import java.io.InterruptedIOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collections; +import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import java.util.Set; -import java.util.TreeMap; -import org.apache.log4j.Level; -import org.apache.log4j.Priority; import org.apache.log4j.Category; -import org.apache.log4j.Logger; +import org.apache.log4j.Level; import org.apache.log4j.MDC; import org.apache.log4j.NDC; +import org.apache.log4j.Priority; import org.apache.log4j.helpers.Loader; -import org.apache.log4j.spi.LocationInfo; - +import org.apache.log4j.helpers.LogLog; // Contributors: Nelson Minar // Wolf Siberski // Anders Kristensen /** - * The internal representation of logging events. When an affirmative decision - * is made to log then a LoggingEvent instance is created. This - * instance is passed around to the different log4j components. - * - *

    - * This class is of concern to those wishing to extend log4j. - *

    - * - *

    Writers of log4j components such as appenders and receivers should be - * aware of that some of the LoggingEvent fields are initialized lazily. - * Therefore, an appender wishing to output data to be later correctly read - * by a receiver, must initialize "lazy" fields prior to writing them out. - * See the {@link #prepareForDeferredProcessing()} method for the exact list.

    - * - *

    Moreover, in the absence of certain fields, receivers must set the - * values of null fields to a default non-null value. For example, in the - * absence of the locationInfo data, the locationInfo field should be - * set to {@link org.apache.log4j.spi.LocationInfo#NA_LOCATION_INFO - * LocationInfo.NA_LOCATION_INFO}. - * - * - * @author Ceki Gülcü - * @author James P. Cakalic - */ -public class LoggingEvent - implements java.io.Serializable { - private static long startTime = System.currentTimeMillis(); + The internal representation of logging events. When an affirmative + decision is made to log then a LoggingEvent instance + is created. This instance is passed around to the different log4j + components. - // Serialization - static final long serialVersionUID = -868428216207166145L; - static final Integer[] PARAM_ARRAY = new Integer[1]; - static final String TO_LEVEL = "toLevel"; - static final Class[] TO_LEVEL_PARAMS = new Class[] { int.class }; - static final Hashtable methodCache = new Hashtable(3); // use a tiny table +

    This class is of concern to those wishing to extend log4j. - /** - * LoggingEvent are stamped with a {@link #sequenceNumber}. The - * sequenceCount static variable keeps track of the current count. - * - * The count starts at 1 (one). - * - * @since 1.3 - */ - private static long sequenceCount = 1; + @author Ceki Gülcü + @author James P. Cakalic - /** - * Fully qualified name of the calling category class. This field does not - * survive serialization. - * - *

    Note that the getLocationInfo() method relies on this fact. - */ - public transient String fqnOfCategoryClass; + @since 0.8.2 */ +public class LoggingEvent implements java.io.Serializable { - /** - * The category of the logging event. This field is not serialized for - * performance reasons. - * - *

    - * It is set by the LoggingEvent constructor or set by a remote entity after - * deserialization. - *

    - */ - private transient Category logger; + private static long startTime = System.currentTimeMillis(); + + /** Fully qualified name of the calling category class. */ + transient public final String fqnOfCategoryClass; /** - * The logger name. + * The category of the logging event. This field is not serialized + * for performance reasons. * - * the 'logger name' variable name ("categoryName") must remain the same - * as prior versions in order to maintain serialization compatibility with - * log4j 1.2.8 - */ - public String categoryName; + *

    It is set by the LoggingEvent constructor or set by a remote + * entity after deserialization. + * + * @deprecated This field will be marked as private or be completely + * removed in future releases. Please do not use it. + * */ + transient private Category logger; - /** - * Level of logging event. Level cannot be serializable because it is a - * flyweight. Due to its special seralization it cannot be declared final - * either. - * - *

    - * This field should not be accessed directly. You shoud use the {@link + /** + *

    The category (logger) name. + * + * @deprecated This field will be marked as private in future + * releases. Please do not access it directly. Use the {@link + * #getLoggerName} method instead. + + * */ + final public String categoryName; + + /** + * Level of logging event. Level cannot be serializable because it + * is a flyweight. Due to its special seralization it cannot be + * declared final either. + * + *

    This field should not be accessed directly. You shoud use the + * {@link #getLevel} method instead. + * + * @deprecated This field will be marked as private in future + * releases. Please do not access it directly. Use the {@link * #getLevel} method instead. - *

    - * - */ - public transient Priority level; + * */ + transient public Priority level; - /** - * The nested diagnostic context (NDC) of logging event. - */ + /** The nested diagnostic context (NDC) of logging event. */ private String ndc; - /** - *

    The properties map is specific for this event.

    - * - *

    When serialized, it contains a copy of MDC properties as well - * as LoggerRepository properties. - *

    - * - *

    It survives serialization.

    - * @since 1.3 - */ - private Map properties; + /** The mapped diagnostic context (MDC) of logging event. */ + private Hashtable mdcCopy; - /** - * Have we tried to do an NDC lookup? If we did, there is no need to do it - * again. Note that its value is always false when serialized. Thus, a - * receiving SocketNode will never use it's own (incorrect) NDC. See also - * writeObject method. - */ + + /** Have we tried to do an NDC lookup? If we did, there is no need + * to do it again. Note that its value is always false when + * serialized. Thus, a receiving SocketNode will never use it's own + * (incorrect) NDC. See also writeObject method. */ private boolean ndcLookupRequired = true; - /** - * The application supplied message of logging event. - */ - private transient Object message; - /** - * The application supplied message rendered through the log4j objet - * rendering mechanism. - */ + /** Have we tried to do an MDC lookup? If we did, there is no need + * to do it again. Note that its value is always false when + * serialized. See also the getMDC and getMDCCopy methods. */ + private boolean mdcCopyLookupRequired = true; + + /** The application supplied message of logging event. */ + transient private Object message; + + /** The application supplied message rendered through the log4j + objet rendering mechanism.*/ private String renderedMessage; - /** - * The name of thread in which this logging event was generated. - */ + /** The name of thread in which this logging event was generated. */ private String threadName; - /** - * This variable contains information about this event's throwable - */ + + /** This + variable contains information about this event's throwable + */ private ThrowableInformation throwableInfo; - /** - * The number of milliseconds elapsed from 1/1/1970 until logging event was - * created. - */ - public long timeStamp; + /** The number of milliseconds elapsed from 1/1/1970 until logging event + was created. */ + public final long timeStamp; + /** Location information for the caller. */ + private LocationInfo locationInfo; - /** - * A unique sequence number for this logging event. - * - * @since 1.3 - */ - private long sequenceNumber; + // Serialization + static final long serialVersionUID = -868428216207166145L; - /** - * Location information for the caller. - */ - private LocationInfo locationInfo; + static final Integer[] PARAM_ARRAY = new Integer[1]; + static final String TO_LEVEL = "toLevel"; + static final Class[] TO_LEVEL_PARAMS = new Class[] {int.class}; + static final Hashtable methodCache = new Hashtable(3); // use a tiny table /** - * Returns the sequence count for this JVM. - * @return the current sequence count for this JVM - */ - public static synchronized long getSequenceCount() { - return sequenceCount; - } - - /** - * The no-argument constructor for LoggingEvent. This method is the recommended - * constructor for creating LoggingEvent instances. - * - * @since 1.3 - */ - public LoggingEvent() { - } + Instantiate a LoggingEvent from the supplied parameters. - /** - * Instantiate a LoggingEvent from the supplied parameters. - * - *

    Note that many of the LoggingEvent fields are initialized when actually - * needed. For more information please refer to the comments for the - * LoggingEvent class at the top of this page. - *

    - * - * @param logger The logger of this event. - * @param level The level of this event. - * @param message The message of this event. - * @param throwable The throwable of this event. - */ - public LoggingEvent(String fqnOfLoggerClass, Category logger, Priority level, Object message, Throwable throwable) { - this(fqnOfLoggerClass, logger, System.currentTimeMillis(), level, message, throwable); +

    Except {@link #timeStamp} all the other fields of + LoggingEvent are filled when actually needed. +

    + @param logger The logger generating this event. + @param level The level of this event. + @param message The message of this event. + @param throwable The throwable of this event. */ + public LoggingEvent(String fqnOfCategoryClass, Category logger, + Priority level, Object message, Throwable throwable) { + this.fqnOfCategoryClass = fqnOfCategoryClass; + this.logger = logger; + this.categoryName = logger.getName(); + this.level = level; + this.message = message; + if(throwable != null) { + this.throwableInfo = new ThrowableInformation(throwable, logger); + } + timeStamp = System.currentTimeMillis(); } /** - * Instantiate a LoggingEvent from the supplied parameters. - * - *

    Note that many of the LoggingEvent fields are initialized lazily. For - * more information please refer to the comments for the LoggingEvent class - * at the top of this page. - *

    - * - * @param fqnOfCategoryClass The category of this event. - * @param logger The logger - * @param timeStamp the timestamp of this logging event - * @param level The level of this event. - * @param message The message of this event. - * @param throwable The throwable of this event. - * @deprecated Please use the no argument constructor and the setter methods - * instead. - */ - public LoggingEvent(String fqnOfCategoryClass, Category logger, long timeStamp, Priority level, Object message, - Throwable throwable) { + Instantiate a LoggingEvent from the supplied parameters. + +

    Except {@link #timeStamp} all the other fields of + LoggingEvent are filled when actually needed. +

    + @param logger The logger generating this event. + @param timeStamp the timestamp of this logging event + @param level The level of this event. + @param message The message of this event. + @param throwable The throwable of this event. */ + public LoggingEvent(String fqnOfCategoryClass, Category logger, + long timeStamp, Priority level, Object message, + Throwable throwable) { this.fqnOfCategoryClass = fqnOfCategoryClass; this.logger = logger; this.categoryName = logger.getName(); this.level = level; this.message = message; - - if (throwable != null) { - this.throwableInfo = new ThrowableInformation(throwable); + if(throwable != null) { + this.throwableInfo = new ThrowableInformation(throwable, logger); } this.timeStamp = timeStamp; - synchronized(LoggingEvent.class) { - sequenceNumber = sequenceCount++; - } } /** @@ -274,7 +209,7 @@ public LoggingEvent(String fqnOfCategoryClass, Category logger, long timeStamp, @param properties MDC properties */ public LoggingEvent(final String fqnOfCategoryClass, - final Logger logger, + final Category logger, final long timeStamp, final Level level, final Object message, @@ -283,618 +218,261 @@ public LoggingEvent(final String fqnOfCategoryClass, final String ndc, final LocationInfo info, final java.util.Map properties) { - this(); - this.setFQNOfLoggerClass(fqnOfCategoryClass); - this.setLogger(logger); - this.setLevel(level); - this.setMessage(message); - this.setThrowableInformation(throwable); - this.setTimeStamp(timeStamp); - this.setThreadName(threadName); - this.setNDC(ndc); - this.setLocationInformation(info); - if (properties instanceof Hashtable) { - this.setProperties((Hashtable) properties); + super(); + this.fqnOfCategoryClass = fqnOfCategoryClass; + this.logger = logger; + if (logger != null) { + categoryName = logger.getName(); } else { - this.setProperties(new Hashtable(properties)); + categoryName = null; + } + this.level = level; + this.message = message; + if(throwable != null) { + this.throwableInfo = throwable; } - } - - - /** - * Two events are considerd equal if they refer to the same instance, or if - * both their timestamps and sequence numbers match. - */ - public boolean equals(Object rObject) { - if (this == rObject) { - return true; - } - - if (! (rObject instanceof LoggingEvent)) { - return false; - } - - LoggingEvent rEvent = (LoggingEvent)rObject; - - if (timeStamp != rEvent.timeStamp) { - return false; - } - - if (sequenceNumber != rEvent.sequenceNumber) { - return false; - } - // at this point, the probability of the two events being equal is - // extremely high. The next few test is optimized to take advantage of - // this knowlege. (We only compare string lengths instead of invoking - // string.equals which is much slower when the two string are equal. - - if(categoryName != null && rEvent.categoryName != null) { - if(categoryName.length() != rEvent.categoryName.length()) { - return false; + this.timeStamp = timeStamp; + this.threadName = threadName; + ndcLookupRequired = false; + this.ndc = ndc; + this.locationInfo = info; + mdcCopyLookupRequired = false; + if (properties != null) { + mdcCopy = new java.util.Hashtable(properties); } - } else if(categoryName != rEvent.categoryName) { - // of categoryNames is null while the other is not, they can't possibly - // be equal - return false; } - - - - // If timestamp, sequenceNumber and categoryName length are equal than the - // events are assumed to be equal. - return true; - } - /** - * The hashcode is computed as XOR of the lower 32 bits of sequenceNumber and - * bits 21 to 53 of timeStamp; - */ - public int hashCode() { - // 2^20 millis corresponds to 17 minutes - return (int)((timeStamp >> 20) ^ (sequenceNumber & 0xFFFFFFFF)); - } - - - /** - * Check for the existence of location information without creating it (a byproduct of calling - * getLocationInformation). - */ - public boolean locationInformationExists() { - return (locationInfo != null); - } - - - /** - * Get the location information for this logging event. If location - * information is null at the time of its invocation, this method extracts - * location information. The collected information is cached for future use. - * - *

    Note that after serialisation, it is impossible to correctly extract - * location information. In that case null is returned.

    + Set the location information for this logging event. The collected + information is cached for future use. */ public LocationInfo getLocationInformation() { - // we rely on the fact that fqnOfLoggerClass does not survive - // serialization - if (locationInfo == null && fqnOfCategoryClass != null) { + if(locationInfo == null) { locationInfo = new LocationInfo(new Throwable(), fqnOfCategoryClass); } return locationInfo; } - /** - * Set the location information for this logging event. - * @since 1.3 - */ - public void setLocationInformation(LocationInfo li) { - if (locationInfo != null) { - throw new IllegalStateException("LocationInformation has been already set."); - } - locationInfo = li; - } - - - /** - * Return the level of this event. - */ + * Return the level of this event. Use this form instead of directly + * accessing the level field. */ public Level getLevel() { - return (Level)level; - } - - - /** - * Set the level of this event. The level can be set at most once. - * - * @param level The level to set. - * @throws IllegalStateException if the level has been already set. - * @since 1.3 - */ - public void setLevel(Level level) { - if (this.level != null) { - throw new IllegalStateException("The level has been already set for this event."); - } - this.level = level; - } - - - /** - * Returns the logger of this event. May be null because events after - * serialization do not have a logger. - * - * @since 1.3 - **/ - public Logger getLogger() { - if (logger instanceof Logger) { - return (Logger) logger; - } - return null; + return (Level) level; } - /** - * Set the logger of this event. Calling this method also sets the loggerName - * for the event. The logger can be set at most once. - * - * Moreover, if the loggerName has been already set, this method will throw - * an {@link IllegalStateException}. - * - * @throws IllegalStateException - */ - public void setLogger(Logger logger) { - if (this.logger != null) { - throw new IllegalStateException("logger has been already set to [" + this.logger.getName() + "]."); - } - - if (this.categoryName != null) { - throw new IllegalStateException("loggerName has been already set to [" + this.categoryName + "], logger " - + logger.getName() + "] is invalid"); - } - - this.logger = logger; - this.categoryName = logger.getName(); - } - - - /** - * Return the name of the logger. + * Return the name of the logger. Use this form instead of directly + * accessing the categoryName field. */ public String getLoggerName() { return categoryName; } + /** + * Gets the logger of the event. + * Use should be restricted to cloning events. + * @since 1.2.15 + */ + public Category getLogger() { + return logger; + } /** - * Set the loggerName for this event. The loggerName can be set at most once. - * - * @param loggerName The loggerName to set. - * @throws IllegalStateException if loggerName is already set - * @since 1.3 - */ - public void setLoggerName(String loggerName) - throws IllegalStateException { - if (this.categoryName != null) { - throw new IllegalStateException("loggerName has been already set to [" + this.categoryName + "]."); - } else { - this.categoryName = loggerName; - } - } + Return the message for this logging event. +

    Before serialization, the returned object is the message + passed by the user to generate the logging event. After + serialization, the returned value equals the String form of the + message possibly after object rendering. - /** - * Return the message for this logging event. - * - *

    - * Before serialization, the returned object is the message passed by the - * user to generate the logging event. After serialization, the returned - * value equals the String form of the message possibly after object - * rendering. - *

    - * - * @since 1.1 - */ - public Object getMessage() { - if (message != null) { + @since 1.1 */ + public + Object getMessage() { + if(message != null) { return message; } else { return getRenderedMessage(); } } - - /** - * Set the message for this event. The - * @param message The message to set. - * @since 1.3 - */ - public void setMessage(Object message) { - if (this.message != null) { - throw new IllegalStateException("The message for this event has been set alredy."); - } - - // After serialisation, message will be null and renderedMessage will be non-null. - if (this.renderedMessage != null) { - throw new IllegalStateException("The message cannot be set if the renderedMessage has been set."); - } - this.message = message; - } - - /** - * This method returns the NDC for this event. It will return the correct - * content even if the event was generated in a different thread or even on - * a different machine. The {@link NDC#get} method should never be - * called directly. - */ - public String getNDC() { - if (ndcLookupRequired) { + * This method returns the NDC for this event. It will return the + * correct content even if the event was generated in a different + * thread or even on a different machine. The {@link NDC#get} method + * should never be called directly. */ + public + String getNDC() { + if(ndcLookupRequired) { ndcLookupRequired = false; ndc = NDC.get(); } - return ndc; } /** - * This method sets the NDC string for this event. - * @throws IllegalStateException if ndc had been already set. - * @since 1.3 - */ - public void setNDC(String ndcString) { - if (this.ndc != null) { - throw new IllegalStateException("The ndc has been already set."); - } - ndcLookupRequired = false; - ndc = ndcString; - } - - /** - Returns the the context corresponding to the key - parameter. If there is a local MDC copy, possibly because we are - in a logging server or running inside AsyncAppender, then we - search for the key in MDC copy, if a value is found it is - returned. Otherwise, if the search in MDC copy returns a null - result, then the current thread's MDC is used. - -

    Note that both the local MDC copy and the current - thread's MDC are searched. - - @deprecated use getProperty(String) instead. - - */ - public Object getMDC(final String key) { - // - // could potentially return a LoggerRepository property value - // when there is not an MDC property value - // but the negative consequences should be minimal. - if(properties != null) { - Object r = properties.get(key); - if(r != null) { - return r; - } + Returns the the context corresponding to the key + parameter. If there is a local MDC copy, possibly because we are + in a logging server or running inside AsyncAppender, then we + search for the key in MDC copy, if a value is found it is + returned. Otherwise, if the search in MDC copy returns a null + result, then the current thread's MDC is used. + +

    Note that both the local MDC copy and the current + thread's MDC are searched. + + */ + public + Object getMDC(String key) { + Object r; + // Note the mdcCopy is used if it exists. Otherwise we use the MDC + // that is associated with the thread. + if(mdcCopy != null) { + r = mdcCopy.get(key); + if(r != null) { + return r; } - return MDC.get(key); } - - /** - * Obtain a copy of this thread's MDC prior to serialization or - * asynchronous logging. - * - * @deprecated use initializeProperties(). - */ - public - void getMDCCopy() { - initializeProperties(); - } - - - - /** - * If the properties field is null, this method creates a new properties map - * containing a copy of MDC context and a copy of the properites in - * LoggerRepository generating this event. If properties is non-null, - * this method does nothing. - * - * @since 1.3 - */ - public void initializeProperties() { - - if(properties == null) { - properties = new TreeMap(); - Map mdcMap = MDC.getContext(); - if (mdcMap != null) { - properties.putAll(mdcMap); - } - - if (logger != null) { - LoggerRepository repo = logger.getLoggerRepository(); - if (repo instanceof LoggerRepositoryEx) { - properties.putAll(((LoggerRepositoryEx) repo).getProperties()); - } - } - } - } - - - - /** - * Return a property for this event. The return value can be null. - * - *

    The property is searched first in the properties map specific for this - * event, then in the MDC, then in the logger repository containing the logger - * of this event. - * @since 1.3 - */ - public String getProperty(String key) { - String value = null; - - if (properties != null) { - value = (String)properties.get(key); - - if (value != null) { - return value; - } - } - - // if the key was not found in this even't properties, try the MDC - Object mdcvalue = MDC.get(key); - - if (mdcvalue != null) { - return mdcvalue.toString(); - } - - // if still not found try, the properties in the logger repository - if (logger != null) { - LoggerRepository repo = logger.getLoggerRepository(); - if (repo instanceof LoggerRepositoryEx) { - value = ((LoggerRepositoryEx) repo).getProperty(key); - } - } - - return value; - } - - - /** - * Returns the set of of the key values in the properties - * for the event. - * - * The returned set is unmodifiable by the caller. - * - * @return Set an unmodifiable set of the property keys. - * @since 1.3 - */ - public Set getPropertyKeySet() { - initializeProperties(); - return Collections.unmodifiableSet(properties.keySet()); + return MDC.get(key); } - /** - * Returns the rendered version of the message according to the renderers - * registered in the logger repository. - * - * Only the rendered version survives serialization. - * - */ - public String getRenderedMessage() { - if ((renderedMessage == null) && (message != null)) { - if (message instanceof String) { - renderedMessage = (String)message; - } else { - // The logger has a back-reference to the repository containing it - LoggerRepository repository = logger.getLoggerRepository(); - - if (repository instanceof RendererSupport) { - RendererSupport rs = (RendererSupport)repository; - renderedMessage = rs.getRendererMap().findAndRender(message); - } else { - renderedMessage = message.toString(); - } + Obtain a copy of this thread's MDC prior to serialization or + asynchronous logging. + */ + public + void getMDCCopy() { + if(mdcCopyLookupRequired) { + mdcCopyLookupRequired = false; + // the clone call is required for asynchronous logging. + // See also bug #5932. + Hashtable t = MDC.getContext(); + if(t != null) { + mdcCopy = (Hashtable) t.clone(); } } - - return renderedMessage; } + public + String getRenderedMessage() { + if(renderedMessage == null && message != null) { + if(message instanceof String) { + renderedMessage = (String) message; + } else { + LoggerRepository repository = logger.getLoggerRepository(); - /** - * - * @param renderedMessage The renderedMessage to set. - * @throws IllegalStateException if renderedMessage has been already set. - * @since 1.3 - */ - public void setRenderedMessage(String renderedMessage) - throws IllegalStateException { - if (this.renderedMessage != null) { - throw new IllegalStateException("renderedMessage has been already set."); - } - this.renderedMessage = renderedMessage; + if(repository instanceof RendererSupport) { + RendererSupport rs = (RendererSupport) repository; + renderedMessage= rs.getRendererMap().findAndRender(message); + } else { + renderedMessage = message.toString(); + } + } + } + return renderedMessage; } - /** - * Returns the time when the application started, in milliseconds elapsed - * since 01.01.1970. - */ + Returns the time when the application started, in milliseconds + elapsed since 01.01.1970. */ public static long getStartTime() { return startTime; } - /** - * Returns the sequence number. - * @since 1.3 - */ - public long getSequenceNumber() { - return sequenceNumber; - } - - /** - * Sets the sequence number. - * @since 1.3 - */ - public void setSequenceNumber(long sequenceNumber) { - this.sequenceNumber = sequenceNumber; - } - - /** - * Returns the current thread name, or a past thread name returned by this method. - */ - public String getThreadName() { - if (threadName == null) { - threadName = (Thread.currentThread()).getName(); + public + String getThreadName() { + if(threadName == null) { + threadName = (Thread.currentThread()).getName(); } return threadName; } /** - * Sets the thread name. - * @param threadName The threadName to set. - * @throws IllegalStateException If threadName has been already set. - */ - public void setThreadName(String threadName) - throws IllegalStateException { - if (this.threadName != null) { - throw new IllegalStateException("threadName has been already set"); - } - this.threadName = threadName; - } + Returns the throwable information contained within this + event. May be null if there is no such information. - /** - * Returns the throwable information contained within this event. May be - * null if there is no such information. - * - *

    - * Note that the {@link Throwable} object contained within a {@link - * ThrowableInformation} does not survive serialization. - *

    - * - * @since 1.1 - */ - public ThrowableInformation getThrowableInformation() { +

    Note that the {@link Throwable} object contained within a + {@link ThrowableInformation} does not survive serialization. + + @since 1.1 */ + public + ThrowableInformation getThrowableInformation() { return throwableInfo; } - /** - * Return this event's throwable's string[] representaion. - */ - public String[] getThrowableStrRep() { - if (throwableInfo == null) { - return null; - } else { - return throwableInfo.getThrowableStrRep(); - } - } + Return this event's throwable's string[] representaion. + */ + public + String[] getThrowableStrRep() { - - /** - * Set this event's throwable information. - * @since 1.3 - */ - public void setThrowableInformation(ThrowableInformation ti) { - if (throwableInfo != null) { - throw new IllegalStateException("ThrowableInformation has been already set."); + if(throwableInfo == null) { + return null; } else { - throwableInfo = ti; + return throwableInfo.getThrowableStrRep(); } } - private void readLevel(ObjectInputStream ois) - throws java.io.IOException, ClassNotFoundException { - int p = ois.readInt(); + private + void readLevel(ObjectInputStream ois) + throws java.io.IOException, ClassNotFoundException { + int p = ois.readInt(); try { - String className = (String)ois.readObject(); - - if (className == null) { - level = Level.toLevel(p); + String className = (String) ois.readObject(); + if(className == null) { + level = Level.toLevel(p); } else { - Method m = (Method)methodCache.get(className); - - if (m == null) { - Class clazz = Loader.loadClass(className); - - // Note that we use Class.getDeclaredMethod instead of - // Class.getMethod. This assumes that the Level subclass - // implements the toLevel(int) method which is a - // requirement. Actually, it does not make sense for Level - // subclasses NOT to implement this method. Also note that - // only Level can be subclassed and not Priority. - m = clazz.getDeclaredMethod(TO_LEVEL, TO_LEVEL_PARAMS); - methodCache.put(className, m); - } - - PARAM_ARRAY[0] = new Integer(p); - level = (Level)m.invoke(null, (Object[]) PARAM_ARRAY); + Method m = (Method) methodCache.get(className); + if(m == null) { + Class clazz = Loader.loadClass(className); + // Note that we use Class.getDeclaredMethod instead of + // Class.getMethod. This assumes that the Level subclass + // implements the toLevel(int) method which is a + // requirement. Actually, it does not make sense for Level + // subclasses NOT to implement this method. Also note that + // only Level can be subclassed and not Priority. + m = clazz.getDeclaredMethod(TO_LEVEL, TO_LEVEL_PARAMS); + methodCache.put(className, m); + } + level = (Level) m.invoke(null, new Integer[] { new Integer(p) } ); } - } catch (Exception e) { - //LogLog.warn("Level deserialization failed, reverting to default.", e); - level = Level.toLevel(p); + } catch(InvocationTargetException e) { + if (e.getTargetException() instanceof InterruptedException + || e.getTargetException() instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.warn("Level deserialization failed, reverting to default.", e); + level = Level.toLevel(p); + } catch(NoSuchMethodException e) { + LogLog.warn("Level deserialization failed, reverting to default.", e); + level = Level.toLevel(p); + } catch(IllegalAccessException e) { + LogLog.warn("Level deserialization failed, reverting to default.", e); + level = Level.toLevel(p); + } catch(RuntimeException e) { + LogLog.warn("Level deserialization failed, reverting to default.", e); + level = Level.toLevel(p); } } - private void readObject(ObjectInputStream ois) - throws java.io.IOException, ClassNotFoundException { + throws java.io.IOException, ClassNotFoundException { ois.defaultReadObject(); readLevel(ois); - // Make sure that location info instance is set. - if (locationInfo == null) { - locationInfo = LocationInfo.NA_LOCATION_INFO; + // Make sure that no location info is available to Layouts + if(locationInfo == null) { + locationInfo = new LocationInfo(null, null); } } - - /** - * @return Returns the properties specific for this event. The returned - * value can be null. - * @since 1.3 - */ - public Map getProperties() { - return properties; - } - - - /** - * @param properties The properties to set. - */ - public void setProperties(Hashtable properties) { - this.properties = properties; - } - - - /** - * Set a string property using a key and a string value. since 1.3 - */ - public void setProperty(String key, String value) { - if (properties == null) { - // create a copy of MDC and repository properties - initializeProperties(); - } - - if (value != null) { - properties.put(key, value); - } else { - properties.remove(key); - } - } - - /** - * This method should be called prior to serializing an event. It should also - * be called when using asynchronous logging, before writing the event on - * a database, or as an XML element. - * - * - * @since 1.3 - */ - public void prepareForDeferredProcessing() { - // Aside from returning the current thread name the wgetThreadName + private + void writeObject(ObjectOutputStream oos) throws java.io.IOException { + // Aside from returning the current thread name the wgetThreadName // method sets the threadName variable. this.getThreadName(); @@ -905,34 +483,26 @@ public void prepareForDeferredProcessing() { // setting ndcLookupRequired to false if not already false. this.getNDC(); - // This call has a side effect of creating a copy of MDC context information - // as well as a copy the properties for the containing LoggerRepository. - if(properties == null) { - initializeProperties(); - } + // This call has a side effect of setting this.mdcCopy and + // setting mdcLookupRequired to false if not already false. + this.getMDCCopy(); + // This sets the throwable sting representation of the event throwable. this.getThrowableStrRep(); - - } - private void writeObject(ObjectOutputStream oos) - throws java.io.IOException { - - prepareForDeferredProcessing(); oos.defaultWriteObject(); // serialize this event's level writeLevel(oos); } + private + void writeLevel(ObjectOutputStream oos) throws java.io.IOException { - private void writeLevel(ObjectOutputStream oos) - throws java.io.IOException { oos.writeInt(level.toInt()); Class clazz = level.getClass(); - - if (clazz == Level.class) { + if(clazz == Level.class) { oos.writeObject(null); } else { // writing directly the Class object would be nicer, except that @@ -942,45 +512,130 @@ private void writeLevel(ObjectOutputStream oos) } } - - /** - * Getter for the event's time stamp. The time stamp is calculated starting - * from 1970-01-01 GMT. - * - * @since 1.3 - */ - public long getTimeStamp() { - return timeStamp; + /** + * Set value for MDC property. + * This adds the specified MDC property to the event. + * Access to the MDC is not synchronized, so this + * method should only be called when it is known that + * no other threads are accessing the MDC. + * @since 1.2.15 + * @param propName + * @param propValue + */ + public final void setProperty(final String propName, + final String propValue) { + if (mdcCopy == null) { + getMDCCopy(); + } + if (mdcCopy == null) { + mdcCopy = new Hashtable(); + } + mdcCopy.put(propName, propValue); } + /** + * Return a property for this event. The return value can be null. + * + * Equivalent to getMDC(String) in log4j 1.2. Provided + * for compatibility with log4j 1.3. + * + * @param key property name + * @return property value or null if property not set + * @since 1.2.15 + */ + public final String getProperty(final String key) { + Object value = getMDC(key); + String retval = null; + if (value != null) { + retval = value.toString(); + } + return retval; + } + + /** + * Check for the existence of location information without creating it + * (a byproduct of calling getLocationInformation). + * @return true if location information has been extracted. + * @since 1.2.15 + */ + public final boolean locationInformationExists() { + return (locationInfo != null); + } - /** - * Setter for the even'ts time stamp. - * See also {@link #getTimeStamp}. - * @since 1.3 - */ - public void setTimeStamp(long timeStamp) { - this.timeStamp = timeStamp; - } + /** + * Getter for the event's time stamp. The time stamp is calculated starting + * from 1970-01-01 GMT. + * @return timestamp + * + * @since 1.2.15 + */ + public final long getTimeStamp() { + return timeStamp; + } + /** + * Returns the set of the key values in the properties + * for the event. + * + * The returned set is unmodifiable by the caller. + * + * Provided for compatibility with log4j 1.3 + * + * @return Set an unmodifiable set of the property keys. + * @since 1.2.15 + */ + public Set getPropertyKeySet() { + return getProperties().keySet(); + } - /** - * Get the fully qualified name of the calling logger sub-class/wrapper. - * @since 1.3 - */ - public String getFQNOfLoggerClass() { - return fqnOfCategoryClass; - } + /** + * Returns the set of properties + * for the event. + * + * The returned set is unmodifiable by the caller. + * + * Provided for compatibility with log4j 1.3 + * + * @return Set an unmodifiable map of the properties. + * @since 1.2.15 + */ + public Map getProperties() { + getMDCCopy(); + Map properties; + if (mdcCopy == null) { + properties = new HashMap(); + } else { + properties = mdcCopy; + } + return Collections.unmodifiableMap(properties); + } + /** + * Get the fully qualified name of the calling logger sub-class/wrapper. + * Provided for compatibility with log4j 1.3 + * @return fully qualified class name, may be null. + * @since 1.2.15 + */ + public String getFQNOfLoggerClass() { + return fqnOfCategoryClass; + } - /** - * Set the fully qualified name of the calling logger sub-class/wrapper. - * - * @since 1.3 - * @param fqnOfLoggerClass - */ - public void setFQNOfLoggerClass(String fqnOfLoggerClass) { - this.fqnOfCategoryClass = fqnOfLoggerClass; - } + /** + * This removes the specified MDC property from the event. + * Access to the MDC is not synchronized, so this + * method should only be called when it is known that + * no other threads are accessing the MDC. + * @param propName the property name to remove + * @since 1.2.16 + */ + public Object removeProperty(String propName) { + if (mdcCopy == null) { + getMDCCopy(); + } + if (mdcCopy == null) { + mdcCopy = new Hashtable(); + } + return mdcCopy.remove(propName); + } } diff --git a/src/main/java/org/apache/log4j/spi/LoggingEventFieldResolver.java b/src/main/java/org/apache/log4j/spi/LoggingEventFieldResolver.java deleted file mode 100644 index faed87054f..0000000000 --- a/src/main/java/org/apache/log4j/spi/LoggingEventFieldResolver.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.spi; - -import java.util.ArrayList; -import java.util.List; -import java.util.StringTokenizer; - - - -/** - * A singleton helper utility which accepts a field name - * and a LoggingEvent and returns the - * String value of that field. - * - * This class defines a grammar used in creation of an expression-based Rule. - * - * The only available method is - * Object getField(String fieldName, LoggingEvent event). - * - * Here is a description of the mapping of field names in the grammar - * to fields on the logging event. While the getField method returns an Object, - * the individual types returned per field are described here: - * - * Field Name Field value (String representation Return type - * LOGGER category name (logger) String - * LEVEL level Level - * CLASS locationInformation's class name String - * FILE locationInformation's file name String - * LINE locationInformation's line number String - * METHOD locationInformation's method name String - * MSG message Object - * NDC NDC String - * EXCEPTION throwable string representation ThrowableInformation - * TIMESTAMP timestamp Long - * THREAD thread String - * PROP.keyName entry in the Property hashtable String - * mapped to the key [keyName] - - * NOTE: the values for the 'keyName' portion of the MDC and PROP mappings must - * be an exact match to the key in the hashTable (case sensitive). - * - * If the passed-in field is null or doesn't match an entry - * in the above-described mapping, an exception is thrown. - * - * @author Scott Deboy (sdeboy@apache.org) - * @author Paul Smith (psmith@apache.org) - * - */ -public final class LoggingEventFieldResolver { - /** - * Keyword list. - */ - public static final List KEYWORD_LIST = new ArrayList(); - /** - * LOGGER string literal. - */ - public static final String LOGGER_FIELD = "LOGGER"; - /** - * LEVEL string literal. - */ - public static final String LEVEL_FIELD = "LEVEL"; - /** - * CLASS string literal. - */ - public static final String CLASS_FIELD = "CLASS"; - /** - * FILE string literal. - */ - public static final String FILE_FIELD = "FILE"; - /** - * LINE string literal. - */ - public static final String LINE_FIELD = "LINE"; - /** - * METHOD string literal. - */ - public static final String METHOD_FIELD = "METHOD"; - /** - * MSG string literal. - */ - public static final String MSG_FIELD = "MSG"; - /** - * NDC string literal. - */ - public static final String NDC_FIELD = "NDC"; - /** - * EXCEPTION string literal. - */ - public static final String EXCEPTION_FIELD = "EXCEPTION"; - /** - * TIMESTAMP string literal. - */ - public static final String TIMESTAMP_FIELD = "TIMESTAMP"; - /** - * THREAD string literal. - */ - public static final String THREAD_FIELD = "THREAD"; - /** - * PROP. string literal. - */ - public static final String PROP_FIELD = "PROP."; - /** - * empty string literal. - */ - public static final String EMPTY_STRING = ""; - /** - * LOGGER string literal. - */ - private static final LoggingEventFieldResolver RESOLVER = - new LoggingEventFieldResolver(); - - /** - * Create new instance. - */ - private LoggingEventFieldResolver() { - super(); - KEYWORD_LIST.add(LOGGER_FIELD); - KEYWORD_LIST.add(LEVEL_FIELD); - KEYWORD_LIST.add(CLASS_FIELD); - KEYWORD_LIST.add(FILE_FIELD); - KEYWORD_LIST.add(LINE_FIELD); - KEYWORD_LIST.add(METHOD_FIELD); - KEYWORD_LIST.add(MSG_FIELD); - KEYWORD_LIST.add(NDC_FIELD); - KEYWORD_LIST.add(EXCEPTION_FIELD); - KEYWORD_LIST.add(TIMESTAMP_FIELD); - KEYWORD_LIST.add(THREAD_FIELD); - KEYWORD_LIST.add(PROP_FIELD); - } - - /** - * Apply fields. - * @param replaceText replacement text. - * @param event logging event. - * @return evaluted expression - */ - public String applyFields(final String replaceText, - final LoggingEvent event) { - if (replaceText == null) { - return null; - } - StringTokenizer tokenizer = new StringTokenizer(replaceText); - StringBuffer result = new StringBuffer(); - boolean found = false; - - while (tokenizer.hasMoreTokens()) { - String token = tokenizer.nextToken(); - if (isField(token) || token.toUpperCase().startsWith(PROP_FIELD)) { - result.append(getValue(token, event).toString()); - found = true; - } else { - result.append(token); - } - } - if (found) { - return result.toString(); - } - return null; - } - - /** - * Get singleton instance. - * @return singleton instance - */ - public static LoggingEventFieldResolver getInstance() { - return RESOLVER; - } - - /** - * Determines if specified string is a recognized field. - * @param fieldName field name - * @return true if recognized field. - */ - public boolean isField(final String fieldName) { - if (fieldName != null) { - return (KEYWORD_LIST.contains( - fieldName.toUpperCase()) - || fieldName.toUpperCase().startsWith(PROP_FIELD)); - } - return false; - } - - /** - * Get value of field. - * @param fieldName field - * @param event event - * @return value of field - */ - public Object getValue(final String fieldName, - final LoggingEvent event) { - String upperField = fieldName.toUpperCase(); - LocationInfo info = null; - if (event.locationInformationExists()) { - info = event.getLocationInformation(); - } - if (LOGGER_FIELD.equals(upperField)) { - return event.getLoggerName(); - } else if (LEVEL_FIELD.equals(upperField)) { - return event.getLevel(); - } else if (CLASS_FIELD.equals(upperField)) { - return ((info == null) ? EMPTY_STRING : info.getClassName()); - } else if (FILE_FIELD.equals(upperField)) { - return ((info == null) ? EMPTY_STRING : info.getFileName()); - } else if (LINE_FIELD.equals(upperField)) { - return ((info == null) ? EMPTY_STRING : info.getLineNumber()); - } else if (METHOD_FIELD.equals(upperField)) { - return ((info == null) ? EMPTY_STRING : info.getMethodName()); - } else if (MSG_FIELD.equals(upperField)) { - return event.getMessage(); - } else if (NDC_FIELD.equals(upperField)) { - String ndcValue = event.getNDC(); - return ((ndcValue == null) ? EMPTY_STRING : ndcValue); - } else if (EXCEPTION_FIELD.equals(upperField)) { - String[] throwableRep = event.getThrowableStrRep(); - if (throwableRep == null) { - return EMPTY_STRING; - } else { - return getExceptionMessage(throwableRep); - } - } else if (TIMESTAMP_FIELD.equals(upperField)) { - return new Long(event.getTimeStamp()); - } else if (THREAD_FIELD.equals(upperField)) { - return event.getThreadName(); - } else if (upperField.startsWith(PROP_FIELD)) { - //note: need to use actual fieldname since case matters - String propValue = event.getProperty(fieldName.substring(5)); - return ((propValue == null) ? EMPTY_STRING : propValue); - } - - //there wasn't a match, so throw a runtime exception - throw new IllegalArgumentException("Unsupported field name: " + fieldName); - } - - /** - * Get message from throwable representation. - * @param exception exception - * @return message - */ - private static String getExceptionMessage(final String[] exception) { - StringBuffer buff = new StringBuffer(); - for (int i = 0; i < exception.length; i++) { - buff.append(exception[i]); - } - return buff.toString(); - } -} diff --git a/src/main/java/org/apache/log4j/spi/NOPLogger.java b/src/main/java/org/apache/log4j/spi/NOPLogger.java new file mode 100644 index 0000000000..38b15140d3 --- /dev/null +++ b/src/main/java/org/apache/log4j/spi/NOPLogger.java @@ -0,0 +1,212 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.spi; + +import org.apache.log4j.Appender; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.log4j.Priority; + +import java.util.Enumeration; +import java.util.ResourceBundle; +import java.util.Vector; + +/** + * No-operation implementation of Logger used by NOPLoggerRepository. + * @since 1.2.15 + */ +public final class NOPLogger extends Logger { + /** + * Create instance of Logger. + * @param repo repository, may not be null. + * @param name name, may not be null, use "root" for root logger. + */ + public NOPLogger(NOPLoggerRepository repo, final String name) { + super(name); + this.repository = repo; + this.level = Level.OFF; + this.parent = this; + } + + /** {@inheritDoc} */ + public void addAppender(final Appender newAppender) { + } + + /** {@inheritDoc} */ + public void assertLog(final boolean assertion, final String msg) { + } + + + /** {@inheritDoc} */ + public void callAppenders(final LoggingEvent event) { + } + + /** {@inheritDoc} */ + void closeNestedAppenders() { + } + + /** {@inheritDoc} */ + public void debug(final Object message) { + } + + + /** {@inheritDoc} */ + public void debug(final Object message, final Throwable t) { + } + + /** {@inheritDoc} */ + public void error(final Object message) { + } + + /** {@inheritDoc} */ + public void error(final Object message, final Throwable t) { + } + + + /** {@inheritDoc} */ + public void fatal(final Object message) { + } + + /** {@inheritDoc} */ + public void fatal(final Object message, final Throwable t) { + } + + + /** {@inheritDoc} */ + public Enumeration getAllAppenders() { + return new Vector().elements(); + } + + /** {@inheritDoc} */ + public Appender getAppender(final String name) { + return null; + } + + /** {@inheritDoc} */ + public Level getEffectiveLevel() { + return Level.OFF; + } + + /** {@inheritDoc} */ + public Priority getChainedPriority() { + return getEffectiveLevel(); + } + + /** {@inheritDoc} */ + public ResourceBundle getResourceBundle() { + return null; + } + + + /** {@inheritDoc} */ + public void info(final Object message) { + } + + /** {@inheritDoc} */ + public void info(final Object message, final Throwable t) { + } + + /** {@inheritDoc} */ + public boolean isAttached(Appender appender) { + return false; + } + + /** {@inheritDoc} */ + public boolean isDebugEnabled() { + return false; + } + + /** {@inheritDoc} */ + public boolean isEnabledFor(final Priority level) { + return false; + } + + /** {@inheritDoc} */ + public boolean isInfoEnabled() { + return false; + } + + + /** {@inheritDoc} */ + public void l7dlog(final Priority priority, final String key, final Throwable t) { + } + + /** {@inheritDoc} */ + public void l7dlog(final Priority priority, final String key, final Object[] params, final Throwable t) { + } + + /** {@inheritDoc} */ + public void log(final Priority priority, final Object message, final Throwable t) { + } + + /** {@inheritDoc} */ + public void log(final Priority priority, final Object message) { + } + + /** {@inheritDoc} */ + public void log(final String callerFQCN, final Priority level, final Object message, final Throwable t) { + } + + /** {@inheritDoc} */ + public void removeAllAppenders() { + } + + + /** {@inheritDoc} */ + public void removeAppender(Appender appender) { + } + + /** {@inheritDoc} */ + public void removeAppender(final String name) { + } + + /** {@inheritDoc} */ + public void setLevel(final Level level) { + } + + + /** {@inheritDoc} */ + public void setPriority(final Priority priority) { + } + + /** {@inheritDoc} */ + public void setResourceBundle(final ResourceBundle bundle) { + } + + /** {@inheritDoc} */ + public void warn(final Object message) { + } + + /** {@inheritDoc} */ + public void warn(final Object message, final Throwable t) { + } + + /** {@inheritDoc} */ + public void trace(Object message) { + } + + /** {@inheritDoc} */ + public void trace(Object message, Throwable t) { + } + + /** {@inheritDoc} */ + public boolean isTraceEnabled() { + return false; + } + + +} diff --git a/src/main/java/org/apache/log4j/spi/NOPLoggerRepository.java b/src/main/java/org/apache/log4j/spi/NOPLoggerRepository.java new file mode 100644 index 0000000000..bdb6ed9cd8 --- /dev/null +++ b/src/main/java/org/apache/log4j/spi/NOPLoggerRepository.java @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.spi; + +import org.apache.log4j.Level; +import org.apache.log4j.Category; +import org.apache.log4j.Logger; +import org.apache.log4j.Appender; + +import java.util.Enumeration; +import java.util.Vector; + +/** + * No-operation implementation of LoggerRepository which is used when + * LogManager.repositorySelector is erroneously nulled during class reloading. + * @since 1.2.15 + */ +public final class NOPLoggerRepository implements LoggerRepository { + /** + * {@inheritDoc} + */ + public void addHierarchyEventListener(final HierarchyEventListener listener) { + } + + /** + * {@inheritDoc} + */ + public boolean isDisabled(final int level) { + return true; + } + + /** + * {@inheritDoc} + */ + public void setThreshold(final Level level) { + } + + /** + * {@inheritDoc} + */ + public void setThreshold(final String val) { + } + + /** + * {@inheritDoc} + */ + public void emitNoAppenderWarning(final Category cat) { + } + + /** + * {@inheritDoc} + */ + public Level getThreshold() { + return Level.OFF; + } + + /** + * {@inheritDoc} + */ + public Logger getLogger(final String name) { + return new NOPLogger(this, name); + } + + /** + * {@inheritDoc} + */ + public Logger getLogger(final String name, final LoggerFactory factory) { + return new NOPLogger(this, name); + } + + /** + * {@inheritDoc} + */ + public Logger getRootLogger() { + return new NOPLogger(this, "root"); + } + + /** + * {@inheritDoc} + */ + public Logger exists(final String name) { + return null; + } + + /** + * {@inheritDoc} + */ + public void shutdown() { + } + + /** + * {@inheritDoc} + */ + public Enumeration getCurrentLoggers() { + return new Vector().elements(); + } + + /** + * {@inheritDoc} + */ + public Enumeration getCurrentCategories() { + return getCurrentLoggers(); + } + + + /** + * {@inheritDoc} + */ + public void fireAddAppenderEvent(Category logger, Appender appender) { + } + + /** + * {@inheritDoc} + */ + public void resetConfiguration() { + } +} diff --git a/src/main/java/org/apache/log4j/spi/NOPULogger.java b/src/main/java/org/apache/log4j/spi/NOPULogger.java deleted file mode 100644 index 98fe537f09..0000000000 --- a/src/main/java/org/apache/log4j/spi/NOPULogger.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.spi; - -import org.apache.log4j.ULogger; - - -/** - * A no operation (NOP) implementation of {@link ULogger}. - * - * @author Ceki Gülcü - */ -public final class NOPULogger implements ULogger { - - /** - * The unique instance of NOPLogger. - */ - public static final NOPULogger NOP_LOGGER = new NOPULogger(); - - /** - * There is no point in people creating multiple instances of NullLogger. - * Hence, the private access modifier. - */ - private NOPULogger() { - super(); - } - - /** - * Get instance. - * @param name logger name. - * @return logger. - */ - public static NOPULogger getLogger(final String name) { - return NOP_LOGGER; - } - - /** - * {@inheritDoc} - */ - public boolean isDebugEnabled() { - return false; - } - - /** - * {@inheritDoc} - */ - public void debug(final Object msg) { - // NOP - } - - /** - * {@inheritDoc} - */ - public void debug(final Object parameterizedMsg, final Object param1) { - // NOP - } - - /** - * {@inheritDoc} - */ - public void debug(final String parameterizedMsg, - final Object param1, - final Object param2) { - // NOP - } - - /** - * {@inheritDoc} - */ - public void debug(final Object msg, final Throwable t) { - // NOP - } - - /** - * {@inheritDoc} - */ - public boolean isInfoEnabled() { - // NOP - return false; - } - - /** - * {@inheritDoc} - */ - public void info(final Object msg) { - // NOP - } - - /** - * {@inheritDoc} - */ - public void info(final Object parameterizedMsg, final Object param1) { - // NOP - } - - /** - * {@inheritDoc} - */ - public void info(final String parameterizedMsg, - final Object param1, final Object param2) { - // NOP - } - - /** - * {@inheritDoc} - */ - public void info(final Object msg, final Throwable t) { - // NOP - } - - /** - * {@inheritDoc} - */ - public boolean isWarnEnabled() { - return false; - } - - /** - * {@inheritDoc} - */ - public void warn(final Object msg) { - // NOP - } - - /** - * {@inheritDoc} - */ - public void warn(final Object parameterizedMsg, - final Object param1) { - // NOP - } - - /** - * {@inheritDoc} - */ - public void warn(final String parameterizedMsg, - final Object param1, - final Object param2) { - // NOP - } - - /** - * {@inheritDoc} - */ - public void warn(final Object msg, final Throwable t) { - // NOP - } - - /** - * {@inheritDoc} - */ - public boolean isErrorEnabled() { - return false; - } - - /** - * {@inheritDoc} - */ - public void error(final Object msg) { - // NOP - } - - /** - * {@inheritDoc} - */ - public void error(final Object parameterizedMsg, final Object param1) { - // NOP - } - - /** - * {@inheritDoc} - */ - public void error(final String parameterizedMsg, - final Object param1, - final Object param2) { - // NOP - } - - /** - * {@inheritDoc} - */ - public void error(final Object msg, final Throwable t) { - // NOP - } - -} diff --git a/src/main/java/org/apache/log4j/spi/OptionHandler.java b/src/main/java/org/apache/log4j/spi/OptionHandler.java index b84256bf1c..2c90226825 100644 --- a/src/main/java/org/apache/log4j/spi/OptionHandler.java +++ b/src/main/java/org/apache/log4j/spi/OptionHandler.java @@ -26,6 +26,7 @@ @since 0.8.1 */ public interface OptionHandler { + /** Activate the options that were previously set with calls to option setters. @@ -39,4 +40,23 @@ public interface OptionHandler { org.apache.log4j.FileAppender#setAppend Append} options both of which are ambigous until the other is also set. */ void activateOptions(); + + /** + Return list of strings that the OptionHandler instance recognizes. + + @deprecated We now use JavaBeans style getters/setters. + */ + // String[] getOptionStrings(); + + /** + Set option to value. + +

    The handling of each option depends on the OptionHandler + instance. Some options may become active immediately whereas + other may be activated only when {@link #activateOptions} is + called. + + @deprecated We now use JavaBeans style getters/setters. + */ + //void setOption(String option, String value); } diff --git a/src/main/java/org/apache/log4j/spi/RendererSupport.java b/src/main/java/org/apache/log4j/spi/RendererSupport.java index 63726bb4e7..9d69faa731 100644 --- a/src/main/java/org/apache/log4j/spi/RendererSupport.java +++ b/src/main/java/org/apache/log4j/spi/RendererSupport.java @@ -15,6 +15,7 @@ * limitations under the License. */ + package org.apache.log4j.spi; import org.apache.log4j.or.ObjectRenderer; @@ -22,7 +23,11 @@ public interface RendererSupport { - public RendererMap getRendererMap(); - public void setRenderer(Class renderedClass, ObjectRenderer renderer); + public + RendererMap getRendererMap(); + + public + void setRenderer(Class renderedClass, ObjectRenderer renderer); + } diff --git a/src/main/java/org/apache/log4j/spi/RepositorySelector.java b/src/main/java/org/apache/log4j/spi/RepositorySelector.java index 7bfb32b183..9a70d6203c 100644 --- a/src/main/java/org/apache/log4j/spi/RepositorySelector.java +++ b/src/main/java/org/apache/log4j/spi/RepositorySelector.java @@ -15,29 +15,35 @@ * limitations under the License. */ + + package org.apache.log4j.spi; /** - * The LogManager uses one (and only one) - * RepositorySelector implementation to select the - * {@link LoggerRepository} for a particular application context. - * - *

    It is the responsability of the RepositorySelector - * implementation to track the application context. Log4j makes no assumptions - * about the application context or on its management. - * - *

    See also {@link org.apache.log4j.LogManager LogManager}. - * - * @author Ceki Gülcü - * @since 1.2 - * */ + + The LogManager uses one (and only one) + RepositorySelector implementation to select the + {@link LoggerRepository} for a particular application context. + +

    It is the responsability of the RepositorySelector + implementation to track the application context. Log4j makes no + assumptions about the application context or on its management. + +

    See also {@link org.apache.log4j.LogManager LogManager}. + + @author Ceki Gülcü + @since 1.2 + + */ public interface RepositorySelector { /** - * Returns a {@link LoggerRepository} depending on the context. Implementors - * must make sure that under all circumstances a valid (non-null) - * LoggerRepository is returned. + Returns a {@link LoggerRepository} depending on the + context. Implementors must make sure that a valid (non-null) + LoggerRepository is returned. */ - public LoggerRepository getLoggerRepository(); + public + LoggerRepository getLoggerRepository(); } + diff --git a/src/main/java/org/apache/log4j/spi/RepositorySelectorEx.java b/src/main/java/org/apache/log4j/spi/RepositorySelectorEx.java deleted file mode 100644 index 91aa86954d..0000000000 --- a/src/main/java/org/apache/log4j/spi/RepositorySelectorEx.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.spi; - - -/** - * The LogManager uses one (and only one) - * RepositorySelector implementation to select the - * {@link LoggerRepository} for a particular application context. - * - *

    It is the responsability of the RepositorySelector - * implementation to track the application context. Log4j makes no assumptions - * about the application context or on its management. - * - *

    See also {@link org.apache.log4j.LogManager LogManager}. - * - * @author Ceki Gülcü - * @since 1.3 - * */ -public interface RepositorySelectorEx extends RepositorySelector { - - - /** - * Remove the repository with the given name from the list maintained by the - * respository selector. - * - *

    When applications are stopped or recycled, this method should be called - * to ensure that the associated repository is recycled as well. After the - * repository is detached from this selector, the returned value, i.e. the - * detached repository, can be used to shutdown the repository. - * - *

    If more than one application share the same logging context, then the - * applications need to coordinate their actions. - * - * @return The LoggerRepository instance that was detached. - * @since 1.3 - */ - LoggerRepository detachRepository(String name); -} diff --git a/src/main/java/org/apache/log4j/spi/RootCategory.java b/src/main/java/org/apache/log4j/spi/RootCategory.java index 0e7ed0bc42..995479129c 100644 --- a/src/main/java/org/apache/log4j/spi/RootCategory.java +++ b/src/main/java/org/apache/log4j/spi/RootCategory.java @@ -19,55 +19,58 @@ import org.apache.log4j.Level; import org.apache.log4j.Logger; +import org.apache.log4j.helpers.LogLog; // Contibutors: Mathias Bogaert /** - * This class is deprecated and will be removed in future releases of log4j. - * - * @author Ceki Gülcü * @deprecated Replaced by {@link RootLogger}. */ -public final class RootCategory extends Logger { +final public class RootCategory extends Logger { + /** The root category names itself as "root". However, the root - category cannot be retrieved by name. + category cannot be retrieved by name. */ - public RootCategory(Level level) { + public + RootCategory(Level level) { super("root"); setLevel(level); } + /** Return the assigned level value without walking the category hierarchy. */ - public final Level getChainedLevel() { + final + public + Level getChainedLevel() { return level; } /** - Setting a null value to the level of the root logger may have catastrophic + Setting a null value to the level of the root category may have catastrophic results. We prevent this here. @since 0.8.3 */ - public final void setLevel(Level level) { - if (level == null) { - if (repository instanceof LoggerRepositoryEx) { - ((LoggerRepositoryEx) repository).addErrorItem( - new ErrorItem( - "You have tried to set a null level to root.", new Exception())); - } - } else { + final + public + void setLevel(Level level) { + if(level == null) { + LogLog.error("You have tried to set a null level to root.", + new Throwable()); + } + else { this.level = level; } } - final - public - void setPriority(Level level) { - setLevel(level); - } - + final + public + void setPriority(Level level) { + setLevel(level); + } + } diff --git a/src/main/java/org/apache/log4j/spi/RootLogger.java b/src/main/java/org/apache/log4j/spi/RootLogger.java index c47295f0d3..a9ffd74228 100644 --- a/src/main/java/org/apache/log4j/spi/RootLogger.java +++ b/src/main/java/org/apache/log4j/spi/RootLogger.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,12 +19,13 @@ import org.apache.log4j.Level; import org.apache.log4j.Logger; +import org.apache.log4j.helpers.LogLog; // Contibutors: Mathias Bogaert /** - RootLogger sits at the top of the category hierachy. It is a + RootLogger sits at the top of the logger hierachy. It is a regular logger except that it provides several guarantees.

    First, it cannot be assigned a null @@ -36,11 +37,9 @@ */ public final class RootLogger extends Logger { - /** - * Constructs using a level. - * The root category names itself as "root". However, the root - * category cannot be retrieved by name. + The root logger names itself as "root". However, the root + logger cannot be retrieved by name. */ public RootLogger(Level level) { super("root"); @@ -48,14 +47,7 @@ public RootLogger(Level level) { } /** - * Constructs using a default {@link Level#DEBUG} threshold level. - */ - public RootLogger() { - this(Level.DEBUG); - } - - /** - Return the assigned level value without walking the category + Return the assigned level value without walking the logger hierarchy. */ public final Level getChainedLevel() { @@ -69,13 +61,11 @@ public final Level getChainedLevel() { @since 0.8.3 */ public final void setLevel(Level level) { if (level == null) { - if (repository instanceof LoggerRepositoryEx) { - ((LoggerRepositoryEx) repository).addErrorItem( - new ErrorItem( - "You have tried to set a null level to root.", new Exception())); - } + LogLog.error( + "You have tried to set a null level to root.", new Throwable()); } else { this.level = level; } } + } diff --git a/src/main/java/org/apache/log4j/spi/SimpleULogger.java b/src/main/java/org/apache/log4j/spi/SimpleULogger.java deleted file mode 100644 index 714a57a668..0000000000 --- a/src/main/java/org/apache/log4j/spi/SimpleULogger.java +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.spi; - -import org.apache.log4j.ULogger; -import org.apache.log4j.helpers.MessageFormatter; - - -/** - * A simple implementation that logs messages of level INFO or higher on - * the console (System.out). - *

    - * The output includes the relative time in milliseconds, thread name, 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. - *

    -176 [main] INFO examples.Sort - Populating an array of 2 elements in reverse.
    -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 msg.
    -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.
    -
    - * - * @author Ceki Gülcü - */ -public final class SimpleULogger implements ULogger { - - /** - * Logger name. - */ - private final String loggerName; - - - /** - * Mark the time when this class gets loaded into memory. - */ - private static long startTime = System.currentTimeMillis(); - - /** - * Line separator. - */ - public static final String LINE_SEPARATOR - = System.getProperty("line.separator"); - - /** - * INFO string literal. - */ - private static final String INFO_STR = "INFO"; - /** - * WARN string literal. - */ - private static final String WARN_STR = "WARN"; - /** - * ERROR string literal. - */ - private static final String ERROR_STR = "ERROR"; - - /** - * Constructor is private to force construction through getLogger. - * @param name logger name - */ - private SimpleULogger(final String name) { - super(); - this.loggerName = name; - } - - /** - * Creates a new instance. - * - * @param name logger name - * @return logger. - */ - public static SimpleULogger getLogger(final String name) { - return new SimpleULogger(name); - } - - /** - * {@inheritDoc} - */ - public boolean isDebugEnabled() { - return false; - } - - /** - * {@inheritDoc} - */ - public void debug(final Object msg) { - // NOP - } - - /** - * {@inheritDoc} - */ - public void debug(final Object parameterizedMsg, final Object param1) { - // NOP - } - - /** - * {@inheritDoc} - */ - public void debug(final String parameterizedMsg, - final Object param1, - final Object param2) { - // NOP - } - - /** - * {@inheritDoc} - */ - public void debug(final Object msg, final Throwable t) { - // NOP - } - - /** - * This is our internal implementation for logging regular (non-parameterized) - * log messages. - * - * @param level level - * @param message message - * @param t throwable - */ - private void log(final String level, - final String message, - final 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 level - * @param parameterizedMsg message pattern - * @param param1 param1 - * @param param2 param2 - */ - private void parameterizedLog(final String level, - final Object parameterizedMsg, - final Object param1, - final 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); - } - } - - /** - * {@inheritDoc} - */ - public boolean isInfoEnabled() { - return true; - } - - /** - * {@inheritDoc} - */ - public void info(final Object msg) { - log(INFO_STR, msg.toString(), null); - } - - - /** - * {@inheritDoc} - */ - public void info(final Object parameterizedMsg, final Object param1) { - parameterizedLog(INFO_STR, parameterizedMsg, param1, null); - } - - /** - * {@inheritDoc} - */ - public void info(final String parameterizedMsg, - final Object param1, - final Object param2) { - parameterizedLog(INFO_STR, parameterizedMsg, param1, param2); - } - - /** - * {@inheritDoc} - */ - public void info(final Object msg, final Throwable t) { - log(INFO_STR, msg.toString(), t); - } - - /** - * {@inheritDoc} - */ - public boolean isWarnEnabled() { - return true; - } - - /** - * {@inheritDoc} - */ - public void warn(final Object msg) { - log(WARN_STR, msg.toString(), null); - } - - /** - * {@inheritDoc} - */ - public void warn(final Object parameterizedMsg, final Object param1) { - parameterizedLog(WARN_STR, parameterizedMsg, param1, null); - } - - /** - * {@inheritDoc} - */ - public void warn(final String parameterizedMsg, - final Object param1, - final Object param2) { - parameterizedLog(WARN_STR, parameterizedMsg, param1, param2); - } - - /** - * {@inheritDoc} - */ - public void warn(final Object msg, final Throwable t) { - log(WARN_STR, msg.toString(), t); - } - - /** - * {@inheritDoc} - */ - public boolean isErrorEnabled() { - return true; - } - - /** - * {@inheritDoc} - */ - public void error(final Object msg) { - log(ERROR_STR, msg.toString(), null); - } - - - /** - * {@inheritDoc} - */ - public void error(final Object parameterizedMsg, final Object param1) { - parameterizedLog(ERROR_STR, parameterizedMsg, param1, null); - } - - /** - * {@inheritDoc} - */ - public void error(final String parameterizedMsg, - final Object param1, - final Object param2) { - parameterizedLog(ERROR_STR, parameterizedMsg, param1, param2); - } - - /** - * {@inheritDoc} - */ - public void error(final Object msg, final Throwable t) { - log(ERROR_STR, msg.toString(), t); - } - -} diff --git a/src/main/java/org/apache/log4j/spi/Thresholdable.java b/src/main/java/org/apache/log4j/spi/Thresholdable.java deleted file mode 100644 index bd8e1f4aa2..0000000000 --- a/src/main/java/org/apache/log4j/spi/Thresholdable.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.spi; - -import org.apache.log4j.Level; - -/** - * An interface that defines the required methods for supporting the - * setting and getting of a level threshold. Components should implement - * this interface if logging events they process should meet a certain - * threshold before being processed further. Examples of this are - * Appenders and Receivers which will not process logging events unless - * the event level is at or greater than a set threshold level. - * - * @author Paul Smith (psmith@apache.org) - * @author Mark Womack - * @since 1.3 - */ -public interface Thresholdable { - /** - * Sets the component theshold to the given level. - * - * @param level The threshold level events must equal or be greater - * than before further processing can be done. - */ - void setThreshold(Level level); - - /** - * Gets the current threshold setting of the component. - * - * @return Level The current threshold level of the component. - */ - Level getThreshold(); - - /** - * Returns true if the given level is equals or greater than the current - * threshold value of the component. - * - * @param level The level to test against the component threshold. - * @return boolean True if level is equal or greater than the - * component threshold. - */ - boolean isAsSevereAsThreshold(Level level); -} diff --git a/src/main/java/org/apache/log4j/spi/ThrowableInformation.java b/src/main/java/org/apache/log4j/spi/ThrowableInformation.java index 32d9e61fb7..033f18ba34 100644 --- a/src/main/java/org/apache/log4j/spi/ThrowableInformation.java +++ b/src/main/java/org/apache/log4j/spi/ThrowableInformation.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,151 +17,80 @@ package org.apache.log4j.spi; -import org.apache.log4j.helpers.PlatformInfo; - -import java.io.IOException; -import java.io.LineNumberReader; -import java.io.PrintWriter; -import java.io.StringReader; -import java.io.StringWriter; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; - +import org.apache.log4j.Category; +import org.apache.log4j.DefaultThrowableRenderer; /** - * ThrowableInformation is log4j's internal representation of throwables. It - * essentially consists of a string array, called 'rep', where the first - * element, that is rep[0], represents the string representation of the - * throwable (i.e. the value you get when you do throwable.toString()) and - * subsequent elements correspond the stack trace with the top most entry of the - * stack corresponding to the second entry of the 'rep' array that is rep[1]. - * - * @author Ceki Gülcü - * - */ + * ThrowableInformation is log4j's internal representation of + * throwables. It essentially consists of a string array, called + * 'rep', where the first element, that is rep[0], represents the + * string representation of the throwable (i.e. the value you get + * when you do throwable.toString()) and subsequent elements + * correspond the stack trace with the top most entry of the stack + * corresponding to the second entry of the 'rep' array that is + * rep[1]. + * + * @author Ceki Gülcü + * + * */ public class ThrowableInformation implements java.io.Serializable { + static final long serialVersionUID = -4748765566864322735L; - private transient Throwable throwable = null; + private transient Throwable throwable; + private transient Category category; private String[] rep; - public ThrowableInformation(final Throwable throwable) { + public + ThrowableInformation(Throwable throwable) { this.throwable = throwable; - ArrayList lines = new ArrayList(); - extractStringRep(throwable, lines); - rep = new String[lines.size()]; - lines.toArray(rep); - } - - public ThrowableInformation(String[] rep) { - this.rep = rep; } /** - * Gets throwable. - * @return throwable, may be null. - * @deprecated + * Create a new instance. + * @param throwable throwable, may not be null. + * @param category category used to obtain ThrowableRenderer, may be null. + * @since 1.2.16 */ - public Throwable getThrowable() { - return throwable; + public ThrowableInformation(Throwable throwable, Category category) { + this.throwable = throwable; + this.category = category; } /** - * Extract string representation of throwable. - * @param t throwable, may not be null. - * @param lines list to receive stack trace, may not be null. + * Create new instance. + * @since 1.2.15 + * @param r String representation of throwable. */ - private static void extractStringRep(final Throwable t, final List lines) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - t.printStackTrace(pw); - pw.flush(); - LineNumberReader reader = new LineNumberReader( - new StringReader(sw.toString())); - try { - String line = reader.readLine(); - while(line != null) { - lines.add(line); - line = reader.readLine(); - } - } catch(IOException ex) { - lines.add(ex.toString()); + public ThrowableInformation(final String[] r) { + if (r != null) { + rep = (String[]) r.clone(); } + } - // Check if the Throwable t has a nested Throwable. If so, invoke - // extractStringRep recursively. - // Note that the Throwable.getCause was added in JDK 1.4. The printStackTrace - // method was modified in JDK 1.4 to handle the nested throwable returned - // by Throwable.getCause. - try { - Class tC = t.getClass(); - Method[] mA = tC.getMethods(); - Method nextThrowableMethod = null; - for (int i = 0; i < mA.length; i++) { - if (("getCause".equals(mA[i].getName()) && !PlatformInfo.isJDK14OrLater()) - || "getRootCause".equals(mA[i].getName()) - || "getNextException".equals(mA[i].getName()) - || "getException".equals(mA[i].getName())) { - // check param types - Class[] params = mA[i].getParameterTypes(); - if ((params == null) || (params.length == 0)) { - // just found the getter for the nested throwable - nextThrowableMethod = mA[i]; - break; // no need to search further + + public + Throwable getThrowable() { + return throwable; + } + + public synchronized String[] getThrowableStrRep() { + if(rep == null) { + ThrowableRenderer renderer = null; + if (category != null) { + LoggerRepository repo = category.getLoggerRepository(); + if (repo instanceof ThrowableRendererSupport) { + renderer = ((ThrowableRendererSupport) repo).getThrowableRenderer(); } - } } - - if (nextThrowableMethod != null) { - // get the nested throwable and log it - Throwable nextT = - (Throwable) nextThrowableMethod.invoke(t, new Object[0]); - if (nextT != null) { - lines.add("Root cause follows."); - extractStringRep(nextT, lines); - } + if (renderer == null) { + rep = DefaultThrowableRenderer.render(throwable); + } else { + rep = renderer.doRender(throwable); } - } catch (Exception e) { - // do nothing } - } - - /** - * Retun a clone of the string representation of the exceptopn (throwable) - * that this object represents. - */ - public String[] getThrowableStrRep() { return (String[]) rep.clone(); } +} - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (!(o instanceof ThrowableInformation)) { - return false; - } - - ThrowableInformation r = (ThrowableInformation) o; - - if (rep == null) { - return (r.rep == null); - } - - // at this point we know that both rep and r.rep are non-null. - if (rep.length != r.rep.length) { - return false; - } - - int len = rep.length; - for (int i = 0; i < len; i++) { - if (!rep[i].equals(r.rep[i])) { - return false; - } - } - return true; - } -} diff --git a/src/main/java/org/apache/log4j/spi/ThrowableRenderer.java b/src/main/java/org/apache/log4j/spi/ThrowableRenderer.java new file mode 100644 index 0000000000..1b83db279a --- /dev/null +++ b/src/main/java/org/apache/log4j/spi/ThrowableRenderer.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.spi; + +/** + * Implemented by classes that render instances of + * java.lang.Throwable (exceptions and errors) + * into a string representation. + * + * @since 1.2.16 + */ +public interface ThrowableRenderer { + /** + * Render Throwable. + * @param t throwable, may not be null. + * @return String representation. + */ + public String[] doRender(Throwable t); +} diff --git a/src/main/java/org/apache/log4j/spi/ThrowableRendererSupport.java b/src/main/java/org/apache/log4j/spi/ThrowableRendererSupport.java new file mode 100644 index 0000000000..08f02a03e7 --- /dev/null +++ b/src/main/java/org/apache/log4j/spi/ThrowableRendererSupport.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.spi; + +/** + * Implemented by logger repositories that support configurable + * rendering of Throwables. + * + * @since 1.2.16 + */ +public interface ThrowableRendererSupport { + /** + * Get throwable renderer. + * @return throwable renderer, may be null. + */ + ThrowableRenderer getThrowableRenderer(); + + /** + * Set throwable renderer. + * @param renderer renderer, may be null. + */ + void setThrowableRenderer(ThrowableRenderer renderer); +} diff --git a/src/main/java/org/apache/log4j/spi/TriggeringEventEvaluator.java b/src/main/java/org/apache/log4j/spi/TriggeringEventEvaluator.java index 9a392506bd..67f4fcd01d 100644 --- a/src/main/java/org/apache/log4j/spi/TriggeringEventEvaluator.java +++ b/src/main/java/org/apache/log4j/spi/TriggeringEventEvaluator.java @@ -17,9 +17,8 @@ package org.apache.log4j.spi; - /** - + Implementions of this interface allow certain appenders to decide when to perform an appender specific action. @@ -30,9 +29,10 @@ @author Ceki Gülcü @since version 1.0 - + */ public interface TriggeringEventEvaluator { + /** Is this the triggering event? */ diff --git a/src/main/java/org/apache/log4j/spi/location/LegacyExtractor.java b/src/main/java/org/apache/log4j/spi/location/LegacyExtractor.java deleted file mode 100644 index 1c0b2623cd..0000000000 --- a/src/main/java/org/apache/log4j/spi/location/LegacyExtractor.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.log4j.spi.location; - -import org.apache.log4j.Layout; -import org.apache.log4j.helpers.PlatformInfo; - -import java.io.PrintWriter; -import java.io.StringWriter; -import org.apache.log4j.spi.LocationInfo; - - -/** - * Extract location information from a throwable. The techniques used here - * work on all JDK platforms including those prior to JDK 1.4. - * - * @since 1.3 - * @author Ceki Gülcü - */ -public class LegacyExtractor { - - - private static StringWriter sw = new StringWriter(); - private static PrintWriter pw = new PrintWriter(sw); - - private LegacyExtractor() { - } - - static public void extract(LocationInfo li, Throwable t, String fqnOfInvokingClass) { - // on AS400, package path separator in stack trace is not dot '.', - // but slash '/' - if (PlatformInfo.isOnAS400()) { - fqnOfInvokingClass = fqnOfInvokingClass.replace('.', '/'); - } - String s; - - // Protect against multiple access to sw. - synchronized (sw) { - t.printStackTrace(pw); - s = sw.toString(); - sw.getBuffer().setLength(0); - } - - //System.out.println("s is ["+s+"]."); - int ibegin; - - //System.out.println("s is ["+s+"]."); - int iend; - - // Given the current structure of log4j, the line - // containing 'fqnOfCallingClass', usually "org.apache.log4j.Logger." - // should be printed just before the caller. - // This method of searching may not be fastest but it's safer - // than counting the stack depth which is not guaranteed to be - // constant across JVM implementations. - ibegin = s.lastIndexOf(fqnOfInvokingClass); - - if (ibegin == -1) { - return; - } - - ibegin = s.indexOf(Layout.LINE_SEP, ibegin); - - if (ibegin == -1) { - return; - } - - ibegin += Layout.LINE_SEP_LEN; - - // determine end of line - iend = s.indexOf(Layout.LINE_SEP, ibegin); - - if (iend == -1) { - return; - } - - // VA has a different stack trace format which doesn't - // need to skip the inital 'at'. The same applied to AS400. - if ((!PlatformInfo.isInVisualAge()) && (!PlatformInfo.isOnAS400())) { - // back up to first blank character - ibegin = s.lastIndexOf("at ", iend); - - if (ibegin == -1) { - return; - } - - // Add 3 to skip "at "; - ibegin += 3; - } - - // everything between is the requested stack item - li.fullInfo = s.substring(ibegin, iend); - setFileName(li, li.fullInfo ); - setClassName(li, li.fullInfo ); - setMethodName(li, li.fullInfo ); - setLineNumber(li, li.fullInfo ); - } - - /** - * Make a best-effort attemt at setting the fike name of the caller. - * This information may not always be available. - */ - static void setFileName(LocationInfo li, String fullInfo) { - if (fullInfo == null) { - li.fileName = LocationInfo.NA; - } else { - int iend = fullInfo.lastIndexOf(':'); - - if (iend == -1) { - li.fileName = LocationInfo.NA; - } else { - int ibegin = fullInfo.lastIndexOf('(', iend - 1); - li.fileName = fullInfo.substring(ibegin + 1, iend); - } - } - } - - /** - * Make a best-effort attemt at setting the class name of the caller. - * This information may not always be available. - */ - static void setClassName(LocationInfo li, String fullInfo) { - if (fullInfo == null) { - li.className = LocationInfo.NA; - return; - } - - // Starting the search from '(' is safer because there is - // potentially a dot between the parentheses. - int iend = fullInfo.lastIndexOf('('); - - if (iend == -1) { - li.className = LocationInfo.NA; - } else { - iend = fullInfo.lastIndexOf('.', iend); - - // This is because a stack trace in VisualAge looks like: - //java.lang.RuntimeException - // java.lang.Throwable() - // java.lang.Exception() - // java.lang.RuntimeException() - // void test.test.B.print() - // void test.test.A.printIndirect() - // void test.test.Run.main(java.lang.String []) - int ibegin = 0; - - if (PlatformInfo.isInVisualAge()) { - ibegin = fullInfo.lastIndexOf(' ', iend) + 1; - } - - if (iend == -1) { - li.className = LocationInfo.NA; - } else { - li.className = fullInfo.substring(ibegin, iend); - } - } - } - - /** - * Make a best-effort attemt at setting the line number of the caller. - * This information may not always be available. - */ - static void setLineNumber(LocationInfo li, String fullInfo) { - if (fullInfo == null) { - li.lineNumber = LocationInfo.NA; - } else { - int iend = fullInfo.lastIndexOf(')'); - int ibegin = fullInfo.lastIndexOf(':', iend - 1); - - if (ibegin == -1) { - li.lineNumber = LocationInfo.NA; - } else { - li.lineNumber = fullInfo.substring(ibegin + 1, iend); - } - } - } - - /** - * Make a best-effort attemt at setting the method name of the caller. - * This information may not always be available. - */ - static void setMethodName(LocationInfo li, String fullInfo) { - if (fullInfo == null) { - li.methodName = LocationInfo.NA; - } else { - int iend = fullInfo.lastIndexOf('('); - int ibegin = fullInfo.lastIndexOf('.', iend); - - if (ibegin == -1) { - li.methodName = LocationInfo.NA; - } else { - li.methodName = fullInfo.substring(ibegin + 1, iend); - } - } - } -} diff --git a/src/main/java/org/apache/log4j/spi/location/StackTraceElementExtractor.java b/src/main/java/org/apache/log4j/spi/location/StackTraceElementExtractor.java deleted file mode 100644 index 382e941d3e..0000000000 --- a/src/main/java/org/apache/log4j/spi/location/StackTraceElementExtractor.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.spi.location; -import org.apache.log4j.spi.LocationInfo; - -import java.lang.reflect.Method; - - -/** - * A faster extractor based on StackTraceElements introduced in JDK 1.4. - * - * The present code uses reflection. Thus, it should compile on all platforms. - * - * @author Martin Schulz - * @author Ceki Gülcü - * - */ -public class StackTraceElementExtractor { - protected static boolean haveStackTraceElement = false; - private static Method getStackTrace = null; - private static Method getClassName = null; - private static Method getFileName = null; - private static Method getMethodName = null; - private static Method getLineNumber = null; - private static Object[] nullArgs = new Object[] { }; - - static { - try { - Class cStackTraceElement = Class.forName("java.lang.StackTraceElement"); - Class[] nullClassArray = new Class[] { }; - getStackTrace = - Throwable.class.getDeclaredMethod("getStackTrace", nullClassArray); - getClassName = - cStackTraceElement.getDeclaredMethod("getClassName", nullClassArray); - getFileName = - cStackTraceElement.getDeclaredMethod("getFileName", nullClassArray); - getMethodName = - cStackTraceElement.getDeclaredMethod("getMethodName", nullClassArray); - getLineNumber = - cStackTraceElement.getDeclaredMethod("getLineNumber", nullClassArray); - haveStackTraceElement = true; - } catch (Throwable e) { - // we should never get here - } - } - - static public void extract(LocationInfo li, Throwable t, String fqnOfInvokingClass) { - if (t == null) { - return; - } - - Object location = null; - try { - Object[] stes = (Object[]) getStackTrace.invoke(t, nullArgs); - - boolean match = false; - for (int i = 0; i < stes.length; i++) { - if (((String) getClassName.invoke(stes[i], nullArgs)).equals( - fqnOfInvokingClass)) { - match = true; - } else if(match) { - location = stes[i]; - break; - } - } - } catch (Throwable e) { - // Extraction failed, not much we could do now. We can't event log this - // failure because if there is one failure, there may be many others which - // are likely to follow. As location extraction is done on a best-effort - // basis, silence is preferable to overwhelming the user... - } - - // If we failed to extract the location line, then default to LocationInfo.NA - if(location == null) { - li.className = LocationInfo.NA; - li.fileName = LocationInfo.NA; - li.lineNumber = LocationInfo.NA; - li.methodName = LocationInfo.NA; - } else { // otherwise, get the real info - setClassName(li, location); - setFileName(li, location); - setMethodName(li, location); - setLineNumber(li, location); - } - } - - /** - Return the fully qualified class name of the caller making the - logging request. - */ - static void setClassName(LocationInfo li, Object location) { - try { - li.className = (String) getClassName.invoke(location, nullArgs); - } catch (Throwable e) { - li.className = LocationInfo.NA; - } - } - - static void setFileName(LocationInfo li, Object location) { - try { - li.fileName = (String) getFileName.invoke(location, nullArgs); - } catch (Throwable e) { - li.fileName = LocationInfo.NA; - } - } - - static void setLineNumber(LocationInfo li, Object location) { - Integer ln = null; - try { - ln = (Integer) getLineNumber.invoke(location, nullArgs); - if (ln.intValue() >= 0) { - li.lineNumber = ln.toString(); - } - } catch (Throwable e) { - li.lineNumber = LocationInfo.NA; - } - } - - static void setMethodName(LocationInfo li, Object location) { - try { - li.methodName = (String) getMethodName.invoke(location, nullArgs); - } catch (Throwable e) { - li.methodName = LocationInfo.NA; - } - } -} diff --git a/src/main/java/org/apache/log4j/spi/package.html b/src/main/java/org/apache/log4j/spi/package.html index af37d2696b..1205833520 100644 --- a/src/main/java/org/apache/log4j/spi/package.html +++ b/src/main/java/org/apache/log4j/spi/package.html @@ -1,4 +1,21 @@ - + diff --git a/src/main/java/org/apache/log4j/test/witness/confParsing.1 b/src/main/java/org/apache/log4j/test/witness/confParsing.1 deleted file mode 100644 index f679458ca5..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/confParsing.1 +++ /dev/null @@ -1,2 +0,0 @@ -[main] DEBUG root - Message 1 -[main] DEBUG root - Message 2 diff --git a/src/main/java/org/apache/log4j/test/witness/confParsing.10 b/src/main/java/org/apache/log4j/test/witness/confParsing.10 deleted file mode 100644 index 6941ab2051..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/confParsing.10 +++ /dev/null @@ -1,2 +0,0 @@ -AVY [main] DEBUG-Message 1 -AVY [main] DEBUG-Message 2 diff --git a/src/main/java/org/apache/log4j/test/witness/confParsing.11 b/src/main/java/org/apache/log4j/test/witness/confParsing.11 deleted file mode 100644 index ef6ea2ad51..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/confParsing.11 +++ /dev/null @@ -1,2 +0,0 @@ -VSUB [main] DEBUG-Message 1 -VSUB [main] DEBUG-Message 2 diff --git a/src/main/java/org/apache/log4j/test/witness/confParsing.2 b/src/main/java/org/apache/log4j/test/witness/confParsing.2 deleted file mode 100644 index e740f81250..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/confParsing.2 +++ /dev/null @@ -1,2 +0,0 @@ -[main] DEBUG root testing - Message 1 -[main] DEBUG root testing - Message 2 diff --git a/src/main/java/org/apache/log4j/test/witness/confParsing.3 b/src/main/java/org/apache/log4j/test/witness/confParsing.3 deleted file mode 100644 index 1f4dfb9de1..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/confParsing.3 +++ /dev/null @@ -1 +0,0 @@ -[main] DEBUG root testing - Message 2 diff --git a/src/main/java/org/apache/log4j/test/witness/confParsing.4 b/src/main/java/org/apache/log4j/test/witness/confParsing.4 deleted file mode 100644 index 63b67e541b..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/confParsing.4 +++ /dev/null @@ -1,3 +0,0 @@ -[main] DEBUG testing - HELLO WORLD -[main] DEBUG root testing - Message 1 -[main] DEBUG root testing - Message 2 diff --git a/src/main/java/org/apache/log4j/test/witness/confParsing.5 b/src/main/java/org/apache/log4j/test/witness/confParsing.5 deleted file mode 100644 index 63b67e541b..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/confParsing.5 +++ /dev/null @@ -1,3 +0,0 @@ -[main] DEBUG testing - HELLO WORLD -[main] DEBUG root testing - Message 1 -[main] DEBUG root testing - Message 2 diff --git a/src/main/java/org/apache/log4j/test/witness/confParsing.6 b/src/main/java/org/apache/log4j/test/witness/confParsing.6 deleted file mode 100644 index e740f81250..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/confParsing.6 +++ /dev/null @@ -1,2 +0,0 @@ -[main] DEBUG root testing - Message 1 -[main] DEBUG root testing - Message 2 diff --git a/src/main/java/org/apache/log4j/test/witness/confParsing.7 b/src/main/java/org/apache/log4j/test/witness/confParsing.7 deleted file mode 100644 index 63b67e541b..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/confParsing.7 +++ /dev/null @@ -1,3 +0,0 @@ -[main] DEBUG testing - HELLO WORLD -[main] DEBUG root testing - Message 1 -[main] DEBUG root testing - Message 2 diff --git a/src/main/java/org/apache/log4j/test/witness/confParsing.8 b/src/main/java/org/apache/log4j/test/witness/confParsing.8 deleted file mode 100644 index 1df45268ef..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/confParsing.8 +++ /dev/null @@ -1,2 +0,0 @@ -[main] DEBUG - Message 1 -[main] DEBUG - Message 2 diff --git a/src/main/java/org/apache/log4j/test/witness/confParsing.9 b/src/main/java/org/apache/log4j/test/witness/confParsing.9 deleted file mode 100644 index 1df45268ef..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/confParsing.9 +++ /dev/null @@ -1,2 +0,0 @@ -[main] DEBUG - Message 1 -[main] DEBUG - Message 2 diff --git a/src/main/java/org/apache/log4j/test/witness/customCat.1 b/src/main/java/org/apache/log4j/test/witness/customCat.1 deleted file mode 100644 index af70b03a1f..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/customCat.1 +++ /dev/null @@ -1,6 +0,0 @@ -TRACE - Message 0 -DEBUG - Message 1 -INFO - Message 2 -WARN - Message 3 -ERROR - Message 4 -LETHAL - Message 5 diff --git a/src/main/java/org/apache/log4j/test/witness/definit.1 b/src/main/java/org/apache/log4j/test/witness/definit.1 deleted file mode 100644 index 802992c422..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/definit.1 +++ /dev/null @@ -1 +0,0 @@ -Hello world diff --git a/src/main/java/org/apache/log4j/test/witness/definit.3 b/src/main/java/org/apache/log4j/test/witness/definit.3 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/org/apache/log4j/test/witness/definit.4 b/src/main/java/org/apache/log4j/test/witness/definit.4 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/org/apache/log4j/test/witness/definit.5 b/src/main/java/org/apache/log4j/test/witness/definit.5 deleted file mode 100644 index 802992c422..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/definit.5 +++ /dev/null @@ -1 +0,0 @@ -Hello world diff --git a/src/main/java/org/apache/log4j/test/witness/definit.6 b/src/main/java/org/apache/log4j/test/witness/definit.6 deleted file mode 100644 index 802992c422..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/definit.6 +++ /dev/null @@ -1 +0,0 @@ -Hello world diff --git a/src/main/java/org/apache/log4j/test/witness/domTest.10 b/src/main/java/org/apache/log4j/test/witness/domTest.10 deleted file mode 100644 index 4a2ce8c062..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/domTest.10 +++ /dev/null @@ -1,2 +0,0 @@ -INFO test.DOMTest - Message 1 -INFO root - Message 1 diff --git a/src/main/java/org/apache/log4j/test/witness/domTest.11 b/src/main/java/org/apache/log4j/test/witness/domTest.11 deleted file mode 100644 index 8c16ea6d90..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/domTest.11 +++ /dev/null @@ -1,2 +0,0 @@ -WARN test.DOMTest - Message 2 -WARN root - Message 2 diff --git a/src/main/java/org/apache/log4j/test/witness/domTest.12 b/src/main/java/org/apache/log4j/test/witness/domTest.12 deleted file mode 100644 index 9960bc1d48..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/domTest.12 +++ /dev/null @@ -1,24 +0,0 @@ -DEBUG test.DOMTest - Message 0 -DEBUG root - Message 0 -INFO test.DOMTest - Message 1 -INFO root - Message 1 -ERROR test.DOMTest - Message 3 -ERROR root - Message 3 -FATAL test.DOMTest - Message 4 -FATAL root - Message 4 -DEBUG test.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -DEBUG root - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -ERROR test.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -ERROR root - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/domTest.4 b/src/main/java/org/apache/log4j/test/witness/domTest.4 deleted file mode 100644 index fe6e2b332e..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/domTest.4 +++ /dev/null @@ -1,12 +0,0 @@ -ERROR test.DOMTest - Message 3 -ERROR root - Message 3 -FATAL test.DOMTest - Message 4 -FATAL root - Message 4 -ERROR test.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -ERROR root - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/domTest.5 b/src/main/java/org/apache/log4j/test/witness/domTest.5 deleted file mode 100644 index 9633880812..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/domTest.5 +++ /dev/null @@ -1,26 +0,0 @@ -DEBUG test.DOMTest - Message 0 -DEBUG root - Message 0 -INFO test.DOMTest - Message 1 -INFO root - Message 1 -WARN test.DOMTest - Message 2 -WARN root - Message 2 -ERROR test.DOMTest - Message 3 -ERROR root - Message 3 -FATAL test.DOMTest - Message 4 -FATAL root - Message 4 -DEBUG test.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -DEBUG root - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -ERROR test.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -ERROR root - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/domTest.6 b/src/main/java/org/apache/log4j/test/witness/domTest.6 deleted file mode 100644 index 3c27dfafc1..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/domTest.6 +++ /dev/null @@ -1,4 +0,0 @@ -INFO test.DOMTest - Message 1 -INFO root - Message 1 -WARN test.DOMTest - Message 2 -WARN root - Message 2 diff --git a/src/main/java/org/apache/log4j/test/witness/domTest.7 b/src/main/java/org/apache/log4j/test/witness/domTest.7 deleted file mode 100644 index 478b640574..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/domTest.7 +++ /dev/null @@ -1,24 +0,0 @@ -DEBUG test.DOMTest - Message 0 -DEBUG root - Message 0 -WARN test.DOMTest - Message 2 -WARN root - Message 2 -ERROR test.DOMTest - Message 3 -ERROR root - Message 3 -FATAL test.DOMTest - Message 4 -FATAL root - Message 4 -DEBUG test.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -DEBUG root - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -ERROR test.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -ERROR root - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/domTest.8 b/src/main/java/org/apache/log4j/test/witness/domTest.8 deleted file mode 100644 index 39a4e528e6..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/domTest.8 +++ /dev/null @@ -1,6 +0,0 @@ -WARN test.DOMTest - Message 2 -WARN root - Message 2 -ERROR test.DOMTest - Message 3 -ERROR root - Message 3 -FATAL test.DOMTest - Message 4 -FATAL root - Message 4 diff --git a/src/main/java/org/apache/log4j/test/witness/domTest.9 b/src/main/java/org/apache/log4j/test/witness/domTest.9 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/org/apache/log4j/test/witness/domTest.A1.1 b/src/main/java/org/apache/log4j/test/witness/domTest.A1.1 deleted file mode 100644 index 5d7b3fa5c2..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/domTest.A1.1 +++ /dev/null @@ -1,39 +0,0 @@ -DEBUG test.DOMTest - Message 0 -DEBUG test.DOMTest - Message 0 -DEBUG root - Message 0 -INFO test.DOMTest - Message 1 -INFO test.DOMTest - Message 1 -INFO root - Message 1 -WARN test.DOMTest - Message 2 -WARN test.DOMTest - Message 2 -WARN root - Message 2 -ERROR test.DOMTest - Message 3 -ERROR test.DOMTest - Message 3 -ERROR root - Message 3 -FATAL test.DOMTest - Message 4 -FATAL test.DOMTest - Message 4 -FATAL root - Message 4 -DEBUG test.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -DEBUG test.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -DEBUG root - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -ERROR test.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -ERROR test.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -ERROR root - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/domTest.A1.2 b/src/main/java/org/apache/log4j/test/witness/domTest.A1.2 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/org/apache/log4j/test/witness/domTest.A1.3 b/src/main/java/org/apache/log4j/test/witness/domTest.A1.3 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/org/apache/log4j/test/witness/domTest.A2.1 b/src/main/java/org/apache/log4j/test/witness/domTest.A2.1 deleted file mode 100644 index 97882605e4..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/domTest.A2.1 +++ /dev/null @@ -1,26 +0,0 @@ -[main] DEBUG org.apache.log4j.xml.test.DOMTest - Message 0 -[main] DEBUG root - Message 0 -[main] INFO org.apache.log4j.xml.test.DOMTest - Message 1 -[main] INFO root - Message 1 -[main] WARN org.apache.log4j.xml.test.DOMTest - Message 2 -[main] WARN root - Message 2 -[main] ERROR org.apache.log4j.xml.test.DOMTest - Message 3 -[main] ERROR root - Message 3 -[main] FATAL org.apache.log4j.xml.test.DOMTest - Message 4 -[main] FATAL root - Message 4 -[main] DEBUG org.apache.log4j.xml.test.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -[main] DEBUG root - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -[main] ERROR org.apache.log4j.xml.test.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) -[main] ERROR root - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/domTest.A2.2 b/src/main/java/org/apache/log4j/test/witness/domTest.A2.2 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/org/apache/log4j/test/witness/domTest.A2.3 b/src/main/java/org/apache/log4j/test/witness/domTest.A2.3 deleted file mode 100644 index 5922655c77..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/domTest.A2.3 +++ /dev/null @@ -1,4 +0,0 @@ -[main] ERROR test.DOMTest - TEST3 Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.test.DOMTest.test(DOMTest.java:XXX) - at org.apache.log4j.xml.test.DOMTest.main(DOMTest.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/enableFlagTest.1 b/src/main/java/org/apache/log4j/test/witness/enableFlagTest.1 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/org/apache/log4j/test/witness/enableFlagTest.2 b/src/main/java/org/apache/log4j/test/witness/enableFlagTest.2 deleted file mode 100644 index b422ddcfaf..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/enableFlagTest.2 +++ /dev/null @@ -1 +0,0 @@ -FATAL [main] test.EnableFlagTest = m5 diff --git a/src/main/java/org/apache/log4j/test/witness/enableFlagTest.3 b/src/main/java/org/apache/log4j/test/witness/enableFlagTest.3 deleted file mode 100644 index 6c81bdce17..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/enableFlagTest.3 +++ /dev/null @@ -1,2 +0,0 @@ -ERROR [main] test.EnableFlagTest = m4 -FATAL [main] test.EnableFlagTest = m5 diff --git a/src/main/java/org/apache/log4j/test/witness/enableFlagTest.4 b/src/main/java/org/apache/log4j/test/witness/enableFlagTest.4 deleted file mode 100644 index 244e782c78..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/enableFlagTest.4 +++ /dev/null @@ -1,3 +0,0 @@ -WARN [main] test.EnableFlagTest = m3 -ERROR [main] test.EnableFlagTest = m4 -FATAL [main] test.EnableFlagTest = m5 diff --git a/src/main/java/org/apache/log4j/test/witness/enableFlagTest.5 b/src/main/java/org/apache/log4j/test/witness/enableFlagTest.5 deleted file mode 100644 index df019ef3fa..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/enableFlagTest.5 +++ /dev/null @@ -1,4 +0,0 @@ -INFO [main] test.EnableFlagTest = m2 -WARN [main] test.EnableFlagTest = m3 -ERROR [main] test.EnableFlagTest = m4 -FATAL [main] test.EnableFlagTest = m5 diff --git a/src/main/java/org/apache/log4j/test/witness/enableFlagTest.6 b/src/main/java/org/apache/log4j/test/witness/enableFlagTest.6 deleted file mode 100644 index 335f6ea0a0..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/enableFlagTest.6 +++ /dev/null @@ -1,5 +0,0 @@ -DEBUG [main] test.EnableFlagTest = m1 -INFO [main] test.EnableFlagTest = m2 -WARN [main] test.EnableFlagTest = m3 -ERROR [main] test.EnableFlagTest = m4 -FATAL [main] test.EnableFlagTest = m5 diff --git a/src/main/java/org/apache/log4j/test/witness/enableFlagTest.7 b/src/main/java/org/apache/log4j/test/witness/enableFlagTest.7 deleted file mode 100644 index 335f6ea0a0..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/enableFlagTest.7 +++ /dev/null @@ -1,5 +0,0 @@ -DEBUG [main] test.EnableFlagTest = m1 -INFO [main] test.EnableFlagTest = m2 -WARN [main] test.EnableFlagTest = m3 -ERROR [main] test.EnableFlagTest = m4 -FATAL [main] test.EnableFlagTest = m5 diff --git a/src/main/java/org/apache/log4j/test/witness/fqcn.1 b/src/main/java/org/apache/log4j/test/witness/fqcn.1 deleted file mode 100644 index 24b03ebd67..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/fqcn.1 +++ /dev/null @@ -1,3 +0,0 @@ -DEBUG x1 (test.FQCNTest#test) - hello -DEBUG x1 (test.FQCNTest#test) - hello world. -DEBUG x1 (test.FQCNTest#test) - hello diff --git a/src/main/java/org/apache/log4j/test/witness/getOptions.1 b/src/main/java/org/apache/log4j/test/witness/getOptions.1 deleted file mode 100644 index 46a2d13694..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/getOptions.1 +++ /dev/null @@ -1,11 +0,0 @@ -log4j.appender.f.Append=false -log4j.appender.f.BufferSize=8192 -log4j.appender.f.BufferedIO=false -log4j.appender.f.File=temp -log4j.appender.f.ImmediateFlush=true -log4j.appender.f.layout.ContentType=text/plain -log4j.appender.f.layout.ConversionPattern=%m%n -log4j.appender.f.layout=org.apache.log4j.PatternLayout -log4j.appender.f=org.apache.log4j.FileAppender -log4j.category.org.apache.log4j=INFO, f -log4j.rootCategory=DEBUG, f diff --git a/src/main/java/org/apache/log4j/test/witness/l7d.1 b/src/main/java/org/apache/log4j/test/witness/l7d.1 deleted file mode 100644 index 0bc132b563..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/l7d.1 +++ /dev/null @@ -1,21 +0,0 @@ -T1 INFO - This is the English, US test. -T1 WARN - Hello world. -T1 ERROR - No resource is associated with key "bogusMsg". -T1 ERROR - bogusMsg -T1 ERROR - This is test number 1 with string argument log4j. -T1 ERROR - No resource is associated with key "bogus2". -T1 INFO - bogus2 -T1 INFO - Ceci est le test en francais pour la France. -T1 WARN - Bonjour la France. -T1 ERROR - No resource is associated with key "bogusMsg". -T1 ERROR - bogusMsg -T1 ERROR - Ceci est le test numero 2 contenant l'argument log4j. -T1 ERROR - No resource is associated with key "bogus2". -T1 INFO - bogus2 -T1 INFO - Ceci est le test en francais pour la p'tite Suisse. -T1 WARN - Bonjour la France. -T1 ERROR - No resource is associated with key "bogusMsg". -T1 ERROR - bogusMsg -T1 ERROR - Ceci est le test numero 3 contenant l'argument log4j. -T1 ERROR - No resource is associated with key "bogus2". -T1 INFO - bogus2 diff --git a/src/main/java/org/apache/log4j/test/witness/mycat.1 b/src/main/java/org/apache/log4j/test/witness/mycat.1 deleted file mode 100644 index 8ab1b55b8e..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/mycat.1 +++ /dev/null @@ -1 +0,0 @@ -some.cat DEBUG - Hello world. diff --git a/src/main/java/org/apache/log4j/test/witness/mycat.2 b/src/main/java/org/apache/log4j/test/witness/mycat.2 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/org/apache/log4j/test/witness/mycat.3 b/src/main/java/org/apache/log4j/test/witness/mycat.3 deleted file mode 100644 index 8ab1b55b8e..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/mycat.3 +++ /dev/null @@ -1 +0,0 @@ -some.cat DEBUG - Hello world. diff --git a/src/main/java/org/apache/log4j/test/witness/propCfg.1 b/src/main/java/org/apache/log4j/test/witness/propCfg.1 deleted file mode 100644 index 802992c422..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/propCfg.1 +++ /dev/null @@ -1 +0,0 @@ -Hello world diff --git a/src/main/java/org/apache/log4j/test/witness/propCfg.2 b/src/main/java/org/apache/log4j/test/witness/propCfg.2 deleted file mode 100644 index e64a372d74..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/propCfg.2 +++ /dev/null @@ -1 +0,0 @@ -DEBUG - Hello world diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.1000 b/src/main/java/org/apache/log4j/test/witness/shallow.1000 deleted file mode 100644 index 7938faf55c..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.1000 +++ /dev/null @@ -1,50 +0,0 @@ -DEBUG NDC [main] org.apache.log4j.test.Shallow Message 0 -DEBUG NDC [main] root Message 0 - INFO NDC [main] org.apache.log4j.test.Shallow Message 1 - INFO NDC [main] root Message 1 - WARN NDC [main] org.apache.log4j.test.Shallow Message 2 - WARN NDC [main] root Message 2 -ERROR NDC [main] org.apache.log4j.test.Shallow Message 3 -ERROR NDC [main] root Message 3 -FATAL NDC [main] org.apache.log4j.test.Shallow Message 4 -FATAL NDC [main] root Message 4 -DEBUG NDC [main] org.apache.log4j.test.Shallow Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -DEBUG NDC [main] root Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) - INFO NDC [main] org.apache.log4j.test.Shallow Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) - INFO NDC [main] root Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) - WARN NDC [main] org.apache.log4j.test.Shallow Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) - WARN NDC [main] root Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -ERROR NDC [main] org.apache.log4j.test.Shallow Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -ERROR NDC [main] root Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -FATAL NDC [main] org.apache.log4j.test.Shallow Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -FATAL NDC [main] root Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.1001 b/src/main/java/org/apache/log4j/test/witness/shallow.1001 deleted file mode 100644 index 9ea45d7d6f..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.1001 +++ /dev/null @@ -1,50 +0,0 @@ -DEBUG NDC [main] org.apache.log4j.test.Shallow (Shallow.java:55) Message 0 -DEBUG NDC [main] org.apache.log4j.test.Shallow (Shallow.java:56) Message 0 - INFO NDC [main] org.apache.log4j.test.Shallow (Shallow.java:58) Message 1 - INFO NDC [main] org.apache.log4j.test.Shallow (Shallow.java:59) Message 1 - WARN NDC [main] org.apache.log4j.test.Shallow (Shallow.java:61) Message 2 - WARN NDC [main] org.apache.log4j.test.Shallow (Shallow.java:62) Message 2 -ERROR NDC [main] org.apache.log4j.test.Shallow (Shallow.java:64) Message 3 -ERROR NDC [main] org.apache.log4j.test.Shallow (Shallow.java:65) Message 3 -FATAL NDC [main] org.apache.log4j.test.Shallow (Shallow.java:67) Message 4 -FATAL NDC [main] org.apache.log4j.test.Shallow (Shallow.java:68) Message 4 -DEBUG NDC [main] org.apache.log4j.test.Shallow (Shallow.java:71) Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -DEBUG NDC [main] org.apache.log4j.test.Shallow (Shallow.java:72) Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) - INFO NDC [main] org.apache.log4j.test.Shallow (Shallow.java:74) Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) - INFO NDC [main] org.apache.log4j.test.Shallow (Shallow.java:75) Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) - WARN NDC [main] org.apache.log4j.test.Shallow (Shallow.java:77) Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) - WARN NDC [main] org.apache.log4j.test.Shallow (Shallow.java:78) Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -ERROR NDC [main] org.apache.log4j.test.Shallow (Shallow.java:80) Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -ERROR NDC [main] org.apache.log4j.test.Shallow (Shallow.java:81) Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -FATAL NDC [main] org.apache.log4j.test.Shallow (Shallow.java:83) Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -FATAL NDC [main] org.apache.log4j.test.Shallow (Shallow.java:84) Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.A1.1 b/src/main/java/org/apache/log4j/test/witness/shallow.A1.1 deleted file mode 100644 index 0f3794caad..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.A1.1 +++ /dev/null @@ -1,50 +0,0 @@ -DEBUG - Message 0 -DEBUG - Message 0 -INFO - Message 1 -INFO - Message 1 -WARN - Message 2 -WARN - Message 2 -ERROR - Message 3 -ERROR - Message 3 -FATAL - Message 4 -FATAL - Message 4 -DEBUG - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -DEBUG - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -INFO - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -INFO - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -WARN - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -WARN - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -ERROR - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -ERROR - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -FATAL - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -FATAL - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.A1.2 b/src/main/java/org/apache/log4j/test/witness/shallow.A1.2 deleted file mode 100644 index 72b8396430..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.A1.2 +++ /dev/null @@ -1,45 +0,0 @@ -DEBUG - Message 0 -INFO - Message 1 -INFO - Message 1 -WARN - Message 2 -WARN - Message 2 -ERROR - Message 3 -ERROR - Message 3 -FATAL - Message 4 -FATAL - Message 4 -DEBUG - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -INFO - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -INFO - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -WARN - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -WARN - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -ERROR - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -ERROR - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -FATAL - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -FATAL - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.A1.3 b/src/main/java/org/apache/log4j/test/witness/shallow.A1.3 deleted file mode 100644 index 2e6ca8185f..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.A1.3 +++ /dev/null @@ -1,50 +0,0 @@ -[main] DEBUG org.apache.log4j.test.Shallow NDC - Message 0 -[main] DEBUG root NDC - Message 0 -[main] INFO org.apache.log4j.test.Shallow NDC - Message 1 -[main] INFO root NDC - Message 1 -[main] WARN org.apache.log4j.test.Shallow NDC - Message 2 -[main] WARN root NDC - Message 2 -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 3 -[main] ERROR root NDC - Message 3 -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 4 -[main] FATAL root NDC - Message 4 -[main] DEBUG org.apache.log4j.test.Shallow NDC - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] DEBUG root NDC - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] INFO org.apache.log4j.test.Shallow NDC - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] INFO root NDC - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] WARN org.apache.log4j.test.Shallow NDC - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] WARN root NDC - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] ERROR root NDC - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] FATAL root NDC - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.A1.4 b/src/main/java/org/apache/log4j/test/witness/shallow.A1.4 deleted file mode 100644 index e6836961eb..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.A1.4 +++ /dev/null @@ -1,40 +0,0 @@ -[main] INFO org.apache.log4j.test.Shallow NDC - Message 1 -[main] INFO root NDC - Message 1 -[main] WARN org.apache.log4j.test.Shallow NDC - Message 2 -[main] WARN root NDC - Message 2 -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 3 -[main] ERROR root NDC - Message 3 -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 4 -[main] FATAL root NDC - Message 4 -[main] INFO org.apache.log4j.test.Shallow NDC - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] INFO root NDC - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] WARN org.apache.log4j.test.Shallow NDC - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] WARN root NDC - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] ERROR root NDC - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] FATAL root NDC - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.A1.5 b/src/main/java/org/apache/log4j/test/witness/shallow.A1.5 deleted file mode 100644 index d40c5d98ac..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.A1.5 +++ /dev/null @@ -1,40 +0,0 @@ -[main] DEBUG root NDC - Message 0 -[main] INFO root NDC - Message 1 -[main] WARN org.apache.log4j.test.Shallow NDC - Message 2 -[main] WARN root NDC - Message 2 -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 3 -[main] ERROR root NDC - Message 3 -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 4 -[main] FATAL root NDC - Message 4 -[main] DEBUG root NDC - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] INFO root NDC - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] WARN org.apache.log4j.test.Shallow NDC - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] WARN root NDC - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] ERROR root NDC - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] FATAL root NDC - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.A1.6 b/src/main/java/org/apache/log4j/test/witness/shallow.A1.6 deleted file mode 100644 index d40c5d98ac..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.A1.6 +++ /dev/null @@ -1,40 +0,0 @@ -[main] DEBUG root NDC - Message 0 -[main] INFO root NDC - Message 1 -[main] WARN org.apache.log4j.test.Shallow NDC - Message 2 -[main] WARN root NDC - Message 2 -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 3 -[main] ERROR root NDC - Message 3 -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 4 -[main] FATAL root NDC - Message 4 -[main] DEBUG root NDC - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] INFO root NDC - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] WARN org.apache.log4j.test.Shallow NDC - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] WARN root NDC - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] ERROR root NDC - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] FATAL root NDC - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.A1.7 b/src/main/java/org/apache/log4j/test/witness/shallow.A1.7 deleted file mode 100644 index 564f22cfc4..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.A1.7 +++ /dev/null @@ -1,25 +0,0 @@ -[main] DEBUG root NDC - Message 0 -[main] INFO root NDC - Message 1 -[main] WARN root NDC - Message 2 -[main] ERROR root NDC - Message 3 -[main] FATAL root NDC - Message 4 -[main] DEBUG root NDC - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] INFO root NDC - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] WARN root NDC - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] ERROR root NDC - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] FATAL root NDC - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.A1.8 b/src/main/java/org/apache/log4j/test/witness/shallow.A1.8 deleted file mode 100644 index c1afbe6d7d..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.A1.8 +++ /dev/null @@ -1,15 +0,0 @@ -[main] WARN root NDC - Message 2 -[main] ERROR root NDC - Message 3 -[main] FATAL root NDC - Message 4 -[main] WARN root NDC - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] ERROR root NDC - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] FATAL root NDC - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.A2.1 b/src/main/java/org/apache/log4j/test/witness/shallow.A2.1 deleted file mode 100644 index a724c6a56a..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.A2.1 +++ /dev/null @@ -1,25 +0,0 @@ -DEBUG - Message 0 -INFO - Message 1 -WARN - Message 2 -ERROR - Message 3 -FATAL - Message 4 -DEBUG - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -INFO - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -WARN - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -ERROR - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -FATAL - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.A2.2 b/src/main/java/org/apache/log4j/test/witness/shallow.A2.2 deleted file mode 100644 index a724c6a56a..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.A2.2 +++ /dev/null @@ -1,25 +0,0 @@ -DEBUG - Message 0 -INFO - Message 1 -WARN - Message 2 -ERROR - Message 3 -FATAL - Message 4 -DEBUG - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -INFO - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -WARN - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -ERROR - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -FATAL - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.A2.3 b/src/main/java/org/apache/log4j/test/witness/shallow.A2.3 deleted file mode 100644 index 1ae373ad70..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.A2.3 +++ /dev/null @@ -1,25 +0,0 @@ -[main] DEBUG org.apache.log4j.test.Shallow NDC - Message 0 -[main] INFO org.apache.log4j.test.Shallow NDC - Message 1 -[main] WARN org.apache.log4j.test.Shallow NDC - Message 2 -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 3 -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 4 -[main] DEBUG org.apache.log4j.test.Shallow NDC - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] INFO org.apache.log4j.test.Shallow NDC - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] WARN org.apache.log4j.test.Shallow NDC - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.A2.4 b/src/main/java/org/apache/log4j/test/witness/shallow.A2.4 deleted file mode 100644 index 1bbfd2398c..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.A2.4 +++ /dev/null @@ -1,20 +0,0 @@ -[main] INFO org.apache.log4j.test.Shallow NDC - Message 1 -[main] WARN org.apache.log4j.test.Shallow NDC - Message 2 -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 3 -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 4 -[main] INFO org.apache.log4j.test.Shallow NDC - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] WARN org.apache.log4j.test.Shallow NDC - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.A2.5 b/src/main/java/org/apache/log4j/test/witness/shallow.A2.5 deleted file mode 100644 index 1df2f98412..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.A2.5 +++ /dev/null @@ -1,15 +0,0 @@ -[main] WARN org.apache.log4j.test.Shallow NDC - Message 2 -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 3 -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 4 -[main] WARN org.apache.log4j.test.Shallow NDC - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.A2.6 b/src/main/java/org/apache/log4j/test/witness/shallow.A2.6 deleted file mode 100644 index 1df2f98412..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.A2.6 +++ /dev/null @@ -1,15 +0,0 @@ -[main] WARN org.apache.log4j.test.Shallow NDC - Message 2 -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 3 -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 4 -[main] WARN org.apache.log4j.test.Shallow NDC - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.A2.7 b/src/main/java/org/apache/log4j/test/witness/shallow.A2.7 deleted file mode 100644 index 1df2f98412..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.A2.7 +++ /dev/null @@ -1,15 +0,0 @@ -[main] WARN org.apache.log4j.test.Shallow NDC - Message 2 -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 3 -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 4 -[main] WARN org.apache.log4j.test.Shallow NDC - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/witness/shallow.A2.8 b/src/main/java/org/apache/log4j/test/witness/shallow.A2.8 deleted file mode 100644 index 1ae373ad70..0000000000 --- a/src/main/java/org/apache/log4j/test/witness/shallow.A2.8 +++ /dev/null @@ -1,25 +0,0 @@ -[main] DEBUG org.apache.log4j.test.Shallow NDC - Message 0 -[main] INFO org.apache.log4j.test.Shallow NDC - Message 1 -[main] WARN org.apache.log4j.test.Shallow NDC - Message 2 -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 3 -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 4 -[main] DEBUG org.apache.log4j.test.Shallow NDC - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] INFO org.apache.log4j.test.Shallow NDC - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] WARN org.apache.log4j.test.Shallow NDC - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] ERROR org.apache.log4j.test.Shallow NDC - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) -[main] FATAL org.apache.log4j.test.Shallow NDC - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.test.Shallow.test(Shallow.java:XXX) - at org.apache.log4j.test.Shallow.main(Shallow.java:XXX) diff --git a/src/main/java/org/apache/log4j/test/xml/domTest1.xml b/src/main/java/org/apache/log4j/test/xml/domTest1.xml deleted file mode 100644 index 91777b3dff..0000000000 --- a/src/main/java/org/apache/log4j/test/xml/domTest1.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/test/xml/domTest10.xml b/src/main/java/org/apache/log4j/test/xml/domTest10.xml deleted file mode 100644 index 835fe05d2b..0000000000 --- a/src/main/java/org/apache/log4j/test/xml/domTest10.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/test/xml/domTest11.xml b/src/main/java/org/apache/log4j/test/xml/domTest11.xml deleted file mode 100644 index bcc71f305f..0000000000 --- a/src/main/java/org/apache/log4j/test/xml/domTest11.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/test/xml/domTest12.xml b/src/main/java/org/apache/log4j/test/xml/domTest12.xml deleted file mode 100644 index 25596412c3..0000000000 --- a/src/main/java/org/apache/log4j/test/xml/domTest12.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/test/xml/domTest2.xml b/src/main/java/org/apache/log4j/test/xml/domTest2.xml deleted file mode 100644 index be42eca487..0000000000 --- a/src/main/java/org/apache/log4j/test/xml/domTest2.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/test/xml/domTest3.xml b/src/main/java/org/apache/log4j/test/xml/domTest3.xml deleted file mode 100644 index bdffa4cc5a..0000000000 --- a/src/main/java/org/apache/log4j/test/xml/domTest3.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/test/xml/domTest4.xml b/src/main/java/org/apache/log4j/test/xml/domTest4.xml deleted file mode 100644 index 32972394ad..0000000000 --- a/src/main/java/org/apache/log4j/test/xml/domTest4.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/test/xml/domTest5.xml b/src/main/java/org/apache/log4j/test/xml/domTest5.xml deleted file mode 100644 index b54807f5f6..0000000000 --- a/src/main/java/org/apache/log4j/test/xml/domTest5.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/test/xml/domTest6.xml b/src/main/java/org/apache/log4j/test/xml/domTest6.xml deleted file mode 100644 index f8da8d2058..0000000000 --- a/src/main/java/org/apache/log4j/test/xml/domTest6.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/test/xml/domTest7.xml b/src/main/java/org/apache/log4j/test/xml/domTest7.xml deleted file mode 100644 index f7355786cb..0000000000 --- a/src/main/java/org/apache/log4j/test/xml/domTest7.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/test/xml/domTest8.xml b/src/main/java/org/apache/log4j/test/xml/domTest8.xml deleted file mode 100644 index 255ee9b55a..0000000000 --- a/src/main/java/org/apache/log4j/test/xml/domTest8.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/test/xml/domTest9.xml b/src/main/java/org/apache/log4j/test/xml/domTest9.xml deleted file mode 100644 index a2e220ceb3..0000000000 --- a/src/main/java/org/apache/log4j/test/xml/domTest9.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/test/xml/ext1.xml b/src/main/java/org/apache/log4j/test/xml/ext1.xml deleted file mode 100644 index 18aa8ce786..0000000000 --- a/src/main/java/org/apache/log4j/test/xml/ext1.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/test/xml/fallback1.xml b/src/main/java/org/apache/log4j/test/xml/fallback1.xml deleted file mode 100644 index 783fdbecaf..0000000000 --- a/src/main/java/org/apache/log4j/test/xml/fallback1.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/test/xml/stressAsyncAppender.xml b/src/main/java/org/apache/log4j/test/xml/stressAsyncAppender.xml deleted file mode 100644 index d29da3c3ae..0000000000 --- a/src/main/java/org/apache/log4j/test/xml/stressAsyncAppender.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/varia/DenyAllFilter.java b/src/main/java/org/apache/log4j/varia/DenyAllFilter.java index 2cd9f44e3b..6c9e949396 100644 --- a/src/main/java/org/apache/log4j/varia/DenyAllFilter.java +++ b/src/main/java/org/apache/log4j/varia/DenyAllFilter.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,9 +17,12 @@ package org.apache.log4j.varia; +import org.apache.log4j.spi.Filter; +import org.apache.log4j.spi.LoggingEvent; + /** - This filter drops all logging events. + This filter drops all logging events.

    You can add this filter to the end of a filter chain to switch from the default "accept all unless instructed otherwise" @@ -29,8 +32,41 @@ @author Ceki Gülcü - @since 0.9.0 - @deprecated Replaced by org.apache.log4j.filters.DenyAllFilter. - */ -public class DenyAllFilter extends org.apache.log4j.filter.DenyAllFilter { + @since 0.9.0 */ +public class DenyAllFilter extends Filter { + + /** + Returns null as there are no options. + + @deprecated We now use JavaBeans introspection to configure + components. Options strings are no longer needed. + */ + public + String[] getOptionStrings() { + return null; + } + + + /** + No options to set. + + @deprecated Use the setter method for the option directly instead + of the generic setOption method. + */ + public + void setOption(String key, String value) { + } + + /** + Always returns the integer constant {@link Filter#DENY} + regardless of the {@link LoggingEvent} parameter. + + @param event The LoggingEvent to filter. + @return Always returns {@link Filter#DENY}. + */ + public + int decide(LoggingEvent event) { + return Filter.DENY; + } } + diff --git a/src/main/java/org/apache/log4j/varia/ExternallyRolledFileAppender.java b/src/main/java/org/apache/log4j/varia/ExternallyRolledFileAppender.java index 732118eeac..26e7d842bc 100644 --- a/src/main/java/org/apache/log4j/varia/ExternallyRolledFileAppender.java +++ b/src/main/java/org/apache/log4j/varia/ExternallyRolledFileAppender.java @@ -17,10 +17,13 @@ package org.apache.log4j.varia; -import java.io.*; -import java.net.Socket; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InterruptedIOException; import java.net.ServerSocket; -import org.apache.log4j.helpers.LogLog; +import java.net.Socket; + import org.apache.log4j.RollingFileAppender; import org.apache.log4j.helpers.LogLog; @@ -43,9 +46,7 @@ @author Ceki Gülcü - @since version 0.9.0 - @deprecated since 1.3, use org.apache.log4j.rolling.RollingFileAppender. - */ + @since version 0.9.0 */ public class ExternallyRolledFileAppender extends RollingFileAppender { /** @@ -104,9 +105,7 @@ void activateOptions() { } } -/** - * @deprecated since log4j 1.3. - */ + class HUP extends Thread { int port; @@ -125,19 +124,20 @@ void run() { while(true) { Socket socket = serverSocket.accept(); LogLog.debug("Connected to client at " + socket.getInetAddress()); - new Thread(new HUPNode(socket, er)).start(); + new Thread(new HUPNode(socket, er), "ExternallyRolledFileAppender-HUP").start(); } - } - catch(Exception e) { - e.printStackTrace(); + } catch(InterruptedIOException e) { + Thread.currentThread().interrupt(); + e.printStackTrace(); + } catch(IOException e) { + e.printStackTrace(); + } catch(RuntimeException e) { + e.printStackTrace(); } } } } -/** - * @deprecated since log4j 1.3. - */ class HUPNode implements Runnable { Socket socket; @@ -152,8 +152,12 @@ class HUPNode implements Runnable { try { dis = new DataInputStream(socket.getInputStream()); dos = new DataOutputStream(socket.getOutputStream()); - } - catch(Exception e) { + } catch(InterruptedIOException e) { + Thread.currentThread().interrupt(); + e.printStackTrace(); + } catch(IOException e) { + e.printStackTrace(); + } catch(RuntimeException e) { e.printStackTrace(); } } @@ -172,8 +176,12 @@ public void run() { dos.writeUTF("Expecting [RollOver] string."); } dos.close(); - } - catch(Exception e) { + } catch(InterruptedIOException e) { + Thread.currentThread().interrupt(); + LogLog.error("Unexpected exception. Exiting HUPNode.", e); + } catch(IOException e) { + LogLog.error("Unexpected exception. Exiting HUPNode.", e); + } catch(RuntimeException e) { LogLog.error("Unexpected exception. Exiting HUPNode.", e); } } diff --git a/src/main/java/org/apache/log4j/varia/FallbackErrorHandler.java b/src/main/java/org/apache/log4j/varia/FallbackErrorHandler.java index cb2562c487..7cbc87de4c 100644 --- a/src/main/java/org/apache/log4j/varia/FallbackErrorHandler.java +++ b/src/main/java/org/apache/log4j/varia/FallbackErrorHandler.java @@ -14,30 +14,125 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + package org.apache.log4j.varia; -import org.apache.log4j.Appender; -import org.apache.log4j.Logger; -import org.apache.log4j.spi.ErrorHandler; -import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.spi.ErrorHandler; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.Appender; +import org.apache.log4j.Logger; +import org.apache.log4j.helpers.LogLog; +import java.util.Vector; +import java.io.InterruptedIOException; /** - ErrorHandler and its implementations are no longer - utilized by Log4j. The ErrorHandler interface and any - implementations of it are only here to provide binary runtime - compatibility with versions previous to 1.3, most specifically - 1.2.xx versions. All methods are NOP's. - - @author Ceki Gülcü - @deprecated As of 1.3 - */ + * + * The FallbackErrorHandler implements the ErrorHandler + * interface such that a secondary appender may be specified. This + * secondary appender takes over if the primary appender fails for + * whatever reason. + * + *

    The error message is printed on System.err, and + * logged in the new secondary appender. + * + * @author Ceki Gücü + * */ public class FallbackErrorHandler implements ErrorHandler { - public void setLogger(Logger logger) {} - public void activateOptions() {} - public void error(String message, Exception e, int errorCode) {} - public void error(String message, Exception e, int errorCode, LoggingEvent event) {} - public void error(String message) {} - public void setAppender(Appender appender) {} - public void setBackupAppender(Appender appender) {} + + + Appender backup; + Appender primary; + Vector loggers; + + public FallbackErrorHandler() { + } + + + /** + Adds the logger passed as parameter to the list of + loggers that we need to search for in case of appender failure. + */ + public + void setLogger(Logger logger) { + LogLog.debug("FB: Adding logger [" + logger.getName() + "]."); + if(loggers == null) { + loggers = new Vector(); + } + loggers.addElement(logger); + } + + + /** + No options to activate. + */ + public + void activateOptions() { + } + + + /** + Prints the message and the stack trace of the exception on + System.err. */ + public + void error(String message, Exception e, int errorCode) { + error(message, e, errorCode, null); + } + + /** + Prints the message and the stack trace of the exception on + System.err. + */ + public + void error(String message, Exception e, int errorCode, LoggingEvent event) { + if (e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.debug("FB: The following error reported: " + message, e); + LogLog.debug("FB: INITIATING FALLBACK PROCEDURE."); + if (loggers != null) { + for(int i = 0; i < loggers.size(); i++) { + Logger l = (Logger) loggers.elementAt(i); + LogLog.debug("FB: Searching for ["+primary.getName()+"] in logger [" + +l.getName() + "]."); + LogLog.debug("FB: Replacing ["+primary.getName()+"] by [" + + backup.getName() + "] in logger ["+ l.getName() +"]."); + l.removeAppender(primary); + LogLog.debug("FB: Adding appender ["+backup.getName()+"] to logger " + + l.getName()); + l.addAppender(backup); + } + } + } + + + /** + Print a the error message passed as parameter on + System.err. + */ + public + void error(String message) { + //if(firstTime) { + //LogLog.error(message); + //firstTime = false; + //} + } + + /** + The appender to which this error handler is attached. + */ + public + void setAppender(Appender primary) { + LogLog.debug("FB: Setting primary appender to [" + primary.getName() + "]."); + this.primary = primary; + } + + /** + Set the backup appender. + */ + public + void setBackupAppender(Appender backup) { + LogLog.debug("FB: Setting backup appender to [" + backup.getName() + "]."); + this.backup = backup; + } + } diff --git a/src/main/java/org/apache/log4j/varia/LevelMatchFilter.java b/src/main/java/org/apache/log4j/varia/LevelMatchFilter.java index 4d48b788ec..f5b378866a 100644 --- a/src/main/java/org/apache/log4j/varia/LevelMatchFilter.java +++ b/src/main/java/org/apache/log4j/varia/LevelMatchFilter.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,14 +17,89 @@ package org.apache.log4j.varia; +import org.apache.log4j.Level; +import org.apache.log4j.spi.Filter; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.helpers.OptionConverter; /** - * LevelMax is not + defined, then there is no maximum acceptable level (ie a + level is never rejected for beeing too "high"/important). + +

    Refer to the {@link + org.apache.log4j.AppenderSkeleton#setThreshold setThreshold} method + available to all appenders extending {@link + org.apache.log4j.AppenderSkeleton} for a more convenient way to + filter out events by level. + + @author Simon Kitching + @author based on code by Ceki Gülcü +*/ +public class LevelRangeFilter extends Filter { + + /** + Do we return ACCEPT when a match occurs. Default is + false, so that later filters get run by default */ + boolean acceptOnMatch = false; + + Level levelMin; + Level levelMax; + + + /** + Return the decision of this filter. + */ + public + int decide(LoggingEvent event) { + if(this.levelMin != null) { + if (event.getLevel().isGreaterOrEqual(levelMin) == false) { + // level of event is less than minimum + return Filter.DENY; + } + } + + if(this.levelMax != null) { + if (event.getLevel().toInt() > levelMax.toInt()) { + // level of event is greater than maximum + // Alas, there is no Level.isGreater method. and using + // a combo of isGreaterOrEqual && !Equal seems worse than + // checking the int values of the level objects.. + return Filter.DENY; + } + } + + if (acceptOnMatch) { + // this filter set up to bypass later filters and always return + // accept if level in range + return Filter.ACCEPT; + } + else { + // event is ok for this filter; allow later filters to have a look.. + return Filter.NEUTRAL; + } + } + + /** + Get the value of the LevelMax option. */ + public + Level getLevelMax() { + return levelMax; + } + + + /** + Get the value of the LevelMin option. */ + public + Level getLevelMin() { + return levelMin; + } + + /** + Get the value of the AcceptOnMatch option. + */ + public + boolean getAcceptOnMatch() { + return acceptOnMatch; + } + + /** + Set the LevelMax option. + */ + public + void setLevelMax(Level levelMax) { + this.levelMax = levelMax; + } + + /** + Set the LevelMin option. + */ + public + void setLevelMin(Level levelMin) { + this.levelMin = levelMin; + } + + /** + Set the AcceptOnMatch option. + */ + public + void setAcceptOnMatch(boolean acceptOnMatch) { + this.acceptOnMatch = acceptOnMatch; + } } + diff --git a/src/main/java/org/apache/log4j/varia/ListAppender.java b/src/main/java/org/apache/log4j/varia/ListAppender.java deleted file mode 100644 index 290c656a1a..0000000000 --- a/src/main/java/org/apache/log4j/varia/ListAppender.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.varia; - -import org.apache.log4j.AppenderSkeleton; -import org.apache.log4j.spi.LoggingEvent; - -import java.util.ArrayList; -import java.util.List; - - -/** - * A very basic appender that takes the events and stores them in to a - * java.util.List for late retrieval. - * - * Note: This implemenation intentionally does not allow direct modification - * of the internal List model to reduce the synchronization complexity that - * this would require. - * - * @see org.apache.log4j.varia.ListModelAppender - * - * @author Paul Smith - * - */ -public final class ListAppender extends AppenderSkeleton { - private List list = new ArrayList(); - - /** - * Constructs a list appender. - */ - public ListAppender() { - super(true); - } - - /** - * Returns a writeable, BUT cloned List of all the LoggingEvents that are contained - * in the internal model. You are free to modify this list without - * worry of synchronization, but note that any modifications to the returned list - * that you do will have NO impact on the internal model of this Appender. - * - * @return Modifiable List - */ - public final List getList() { - synchronized (list) { - return new ArrayList(list); - } - } - - /* - * (non-Javadoc) - * - * @see org.apache.log4j.AppenderSkeleton#append(org.apache.log4j.spi.LoggingEvent) - */ - protected void append(LoggingEvent event) { - event.prepareForDeferredProcessing(); - - // Extract location info now. Later it might not be possible. - event.getLocationInformation(); - - synchronized (list) { - list.add(event); - } - } - - /* - * (non-Javadoc) - * - * @see org.apache.log4j.Appender#close() - */ - public void close() { - closed = true; - } - - /** - * Removes all the Events from the model - */ - public void clearList() { - synchronized (list) { - list.clear(); - } - } - - /** - * Gets whether appender requires a layout. - * @return false - */ - public boolean requiresLayout() { - return false; - } -} diff --git a/src/main/java/org/apache/log4j/varia/ListModelAppender.java b/src/main/java/org/apache/log4j/varia/ListModelAppender.java deleted file mode 100644 index ac09d867c8..0000000000 --- a/src/main/java/org/apache/log4j/varia/ListModelAppender.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.varia; - -import org.apache.log4j.AppenderSkeleton; -import org.apache.log4j.spi.LoggingEvent; - -import javax.swing.DefaultListModel; -import javax.swing.ListModel; - - -/** - * A very basic appender that takes the events and stores them in to a - * ListModel for late retrieval. - * - * @since 1.3 - * - * @author Paul Smith (psmith@apache.org) - * - */ -public final class ListModelAppender extends AppenderSkeleton { - /** - * Default list model. - */ - private final DefaultListModel model = new DefaultListModel(); - - /** - * Constructs a ListModelAppender. - */ - public ListModelAppender() { - super(true); - } - /** - * Returns a reference to the ListModel that contains all the LoggingEvents - * that have been appended to this class. - * - * @return the list model - */ - public ListModel getModel() { - return model; - } - - /** {@inheritDoc} */ - protected void append(final LoggingEvent event) { - model.addElement(event); - } - - /** {@inheritDoc} */ - public void close() { - clearModel(); - } - - /** - * Removes all the Events from the model. - */ - public void clearModel() { - model.clear(); - } - - /** {@inheritDoc} */ - public boolean requiresLayout() { - return false; - } - -} diff --git a/src/main/java/org/apache/log4j/varia/LogFilePatternReceiver.java b/src/main/java/org/apache/log4j/varia/LogFilePatternReceiver.java deleted file mode 100644 index 0965930448..0000000000 --- a/src/main/java/org/apache/log4j/varia/LogFilePatternReceiver.java +++ /dev/null @@ -1,833 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package org.apache.log4j.varia; - -import java.io.BufferedReader; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.MalformedURLException; -import java.net.URL; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; - -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.apache.log4j.helpers.Constants; -import org.apache.log4j.plugins.Receiver; -import org.apache.log4j.rule.ExpressionRule; -import org.apache.log4j.rule.Rule; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.ThrowableInformation; -import org.apache.log4j.spi.LocationInfo; -import org.apache.oro.text.perl.Perl5Util; -import org.apache.oro.text.regex.MalformedPatternException; -import org.apache.oro.text.regex.MatchResult; -import org.apache.oro.text.regex.Pattern; -import org.apache.oro.text.regex.Perl5Compiler; -import org.apache.oro.text.regex.Perl5Matcher; - -/** - * LogFilePatternReceiver can parse and tail log files, converting entries into - * LoggingEvents. If the file doesn't exist when the receiver is initialized, the - * receiver will look for the file once every 10 seconds. - *

    - * This receiver relies on ORO Perl5 features to perform the parsing of text in the - * log file, however the only regular expression field explicitly supported is - * a glob-style wildcard used to ignore fields in the log file if needed. All other - * fields are parsed by using the supplied keywords. - *

    - * Features:
    - * - specify the URL of the log file to be processed
    - * - specify the timestamp format in the file (if one exists)
    - * - specify the pattern (logFormat) used in the log file using keywords, a wildcard character (*) and fixed text
    - * - 'tail' the file (allows the contents of the file to be continually read and new events processed)
    - * - supports the parsing of multi-line messages and exceptions - * - 'hostname' property set to URL host (or 'file' if not available) - * - 'application' property set to URL path (or value of fileURL if not available) - *

    - * Keywords:
    - * TIMESTAMP
    - * LOGGER
    - * LEVEL
    - * THREAD
    - * CLASS
    - * FILE
    - * LINE
    - * METHOD
    - * RELATIVETIME
    - * MESSAGE
    - * NDC
    - * PROP(key)
    - *

    - * Use a * to ignore portions of the log format that should be ignored - *

    - * Example:
    - * If your file's patternlayout is this:
    - * %d %-5p [%t] %C{2} (%F:%L) - %m%n - *

    - * specify this as the log format:
    - * TIMESTAMP LEVEL [THREAD] CLASS (FILE:LINE) - MESSAGE - *

    - * To define a PROPERTY field, use PROP(key) - *

    - * Example:
    - * If you used the RELATIVETIME pattern layout character in the file, - * you can use PROP(RELATIVETIME) in the logFormat definition to assign - * the RELATIVETIME field as a property on the event. - *

    - * If your file's patternlayout is this:
    - * %r [%t] %-5p %c %x - %m%n - *

    - * specify this as the log format:
    - * PROP(RELATIVETIME) [THREAD] LEVEL LOGGER * - MESSAGE - *

    - * Note the * - it can be used to ignore a single word or sequence of words in the log file - * (in order for the wildcard to ignore a sequence of words, the text being ignored must be - * followed by some delimiter, like '-' or '[') - ndc is being ignored in this example. - *

    - * Assign a filterExpression in order to only process events which match a filter. - * If a filterExpression is not assigned, all events are processed. - *

    - * Limitations:
    - * - no support for the single-line version of throwable supported by patternlayout
    - * (this version of throwable will be included as the last line of the message)
    - * - the relativetime patternLayout character must be set as a property: PROP(RELATIVETIME)
    - * - messages should appear as the last field of the logFormat because the variability in message content
    - * - exceptions are converted if the exception stack trace (other than the first line of the exception)
    - * is stored in the log file with a tab followed by the word 'at' as the first characters in the line
    - * - tailing may fail if the file rolls over. - *

    - * Example receiver configuration settings (add these as params, specifying a LogFilePatternReceiver 'plugin'):
    - * param: "timestampFormat" value="yyyy-MM-d HH:mm:ss,SSS"
    - * param: "logFormat" value="RELATIVETIME [THREAD] LEVEL LOGGER * - MESSAGE"
    - * param: "fileURL" value="file:///c:/events.log"
    - * param: "tailing" value="true" - *

    - * This configuration will be able to process these sample events:
    - * 710 [ Thread-0] DEBUG first.logger first - something here something else
    - * 880 [ Thread-2] DEBUG first.logger third - something here something else
    - * 880 [ Thread-0] INFO first.logger first - infomsg-0
    - * java.lang.Exception: someexception-first
    - * at Generator2.run(Generator2.java:102)
    - * - *@author Scott Deboy - */ -public class LogFilePatternReceiver extends Receiver { - private final Set keywords = new HashSet(); - - private static final String PROP_START = "PROP("; - private static final String PROP_END = ")"; - - private static final String LOGGER = "LOGGER"; - private static final String MESSAGE = "MESSAGE"; - private static final String TIMESTAMP = "TIMESTAMP"; - private static final String NDC = "NDC"; - private static final String LEVEL = "LEVEL"; - private static final String THREAD = "THREAD"; - private static final String CLASS = "CLASS"; - private static final String FILE = "FILE"; - private static final String LINE = "LINE"; - private static final String METHOD = "METHOD"; - - private static final String DEFAULT_HOST = "file"; - - //all lines other than first line of exception begin with tab followed by 'at' followed by text - private static final String EXCEPTION_PATTERN = "\tat.*"; - private static final String REGEXP_DEFAULT_WILDCARD = ".+?"; - private static final String REGEXP_GREEDY_WILDCARD = ".+"; - private static final String PATTERN_WILDCARD = "*"; - private static final String DEFAULT_GROUP = "(" + REGEXP_DEFAULT_WILDCARD + ")"; - private static final String GREEDY_GROUP = "(" + REGEXP_GREEDY_WILDCARD + ")"; - private static final String MULTIPLE_SPACES_REGEXP = "[ ]+"; - - private final String newLine = System.getProperty("line.separator"); - - private final String[] emptyException = new String[] { "" }; - - private SimpleDateFormat dateFormat; - private String timestampFormat = "yyyy-MM-d HH:mm:ss,SSS"; - private String logFormat; - private String fileURL; - private String host; - private String path; - private boolean tailing; - private String filterExpression; - - private Perl5Util util = null; - private Perl5Compiler exceptionCompiler = null; - private Perl5Matcher exceptionMatcher = null; - private static final String VALID_DATEFORMAT_CHAR_PATTERN = "[GyMwWDdFEaHkKhmsSzZ]"; - - private Rule expressionRule; - - private Map currentMap; - private List additionalLines; - private List matchingKeywords; - - private String regexp; - private Reader reader; - private String timestampPatternText; - - public LogFilePatternReceiver() { - keywords.add(TIMESTAMP); - keywords.add(LOGGER); - keywords.add(LEVEL); - keywords.add(THREAD); - keywords.add(CLASS); - keywords.add(FILE); - keywords.add(LINE); - keywords.add(METHOD); - keywords.add(MESSAGE); - keywords.add(NDC); - } - - /** - * Accessor - * - * @return file URL - */ - public String getFileURL() { - return fileURL; - } - - /** - * Mutator - * - * @param fileURL - */ - public void setFileURL(String fileURL) { - this.fileURL = fileURL; - } - - /** - * Accessor - * - * @return filter expression - */ - public String getFilterExpression() { - return filterExpression; - } - - /** - * Mutator - * - * @param filterExpression - */ - public void setFilterExpression(String filterExpression) { - this.filterExpression = filterExpression; - } - - /** - * Accessor - * - * @return tailing - */ - public boolean isTailing() { - return tailing; - } - - /** - * Mutator - * - * @param tailing - */ - public void setTailing(boolean tailing) { - this.tailing = tailing; - } - - /** - * Accessor - * - * @return log format - */ - public String getLogFormat() { - return logFormat; - } - - /** - * Mutator - * - * @param logFormat - * the format - */ - public void setLogFormat(String logFormat) { - this.logFormat = logFormat; - } - - /** - * Mutator - * - * @param timestampFormat - */ - public void setTimestampFormat(String timestampFormat) { - this.timestampFormat = timestampFormat; - } - - /** - * Accessor - * - * @return timestamp format - */ - public String getTimestampFormat() { - return timestampFormat; - } - - /** - * Walk the additionalLines list, looking for the EXCEPTION_PATTERN. - *

    - * Return the index of the first matched line minus 1 - * (the match is the 2nd line of an exception) - *

    - * Assumptions:
    - * - the additionalLines list may contain both message and exception lines
    - * - message lines are added to the additionalLines list and then - * exception lines (all message lines occur in the list prior to all - * exception lines) - * - * @return -1 if no exception line exists, line number otherwise - */ - private int getExceptionLine() { - try { - Pattern exceptionPattern = exceptionCompiler.compile(EXCEPTION_PATTERN); - for (int i = 0; i < additionalLines.size(); i++) { - if (exceptionMatcher.matches((String) additionalLines.get(i), exceptionPattern)) { - return i - 1; - } - } - } catch (MalformedPatternException mpe) { - getLogger().warn("Bad pattern: " + EXCEPTION_PATTERN); - } - return -1; - } - - /** - * Combine all message lines occuring in the additionalLines list, adding - * a newline character between each line - *

    - * the event will already have a message - combine this message - * with the message lines in the additionalLines list - * (all entries prior to the exceptionLine index) - * - * @param firstMessageLine primary message line - * @param exceptionLine index of first exception line - * @return message - */ - private String buildMessage(String firstMessageLine, int exceptionLine) { - if (additionalLines.size() == 0 || exceptionLine == 0) { - return firstMessageLine; - } - StringBuffer message = new StringBuffer(); - if (firstMessageLine != null) { - message.append(firstMessageLine); - } - - int linesToProcess = (exceptionLine == -1?additionalLines.size(): exceptionLine); - - for (int i = 0; i < linesToProcess; i++) { - message.append(newLine); - message.append(additionalLines.get(i)); - } - return message.toString(); - } - - /** - * Combine all exception lines occuring in the additionalLines list into a - * String array - *

    - * (all entries equal to or greater than the exceptionLine index) - * - * @param exceptionLine index of first exception line - * @return exception - */ - private String[] buildException(int exceptionLine) { - if (exceptionLine == -1) { - return emptyException; - } - String[] exception = new String[additionalLines.size() - exceptionLine]; - for (int i = 0; i < additionalLines.size() - exceptionLine; i++) { - exception[i] = (String) additionalLines.get(i + exceptionLine); - } - return exception; - } - - /** - * Construct a logging event from currentMap and additionalLines - * (additionalLines contains multiple message lines and any exception lines) - *

    - * CurrentMap and additionalLines are cleared in the process - * - * @return event - */ - private LoggingEvent buildEvent() { - if (currentMap.size() == 0) { - if (additionalLines.size() > 0) { - for (Iterator iter = additionalLines.iterator();iter.hasNext();) { - getLogger().info("found non-matching line: " + iter.next()); - } - } - additionalLines.clear(); - return null; - } - //the current map contains fields - build an event - int exceptionLine = getExceptionLine(); - String[] exception = buildException(exceptionLine); - - //messages are listed before exceptions in additionallines - if (additionalLines.size() > 0 && exceptionLine != 0) { - currentMap.put(MESSAGE, buildMessage((String) currentMap.get(MESSAGE), - exceptionLine)); - } - LoggingEvent event = convertToEvent(currentMap, exception); - currentMap.clear(); - additionalLines.clear(); - return event; - } - - /** - * Read, parse and optionally tail the log file, converting entries into logging events. - * - * A runtimeException is thrown if the logFormat pattern is malformed - * according to ORO's Perl5Compiler. - * - * @param unbufferedReader - * @throws IOException - */ - protected void process(Reader unbufferedReader) throws IOException { - BufferedReader bufferedReader = new BufferedReader(unbufferedReader); - - Perl5Compiler compiler = new Perl5Compiler(); - Pattern regexpPattern = null; - try { - regexpPattern = compiler.compile(regexp); - } catch (MalformedPatternException mpe) { - throw new RuntimeException("Bad pattern: " + regexp); - } - - Perl5Matcher eventMatcher = new Perl5Matcher(); - String line = null; - getLogger().debug("tailing file: " + tailing); - do { - while ((line = bufferedReader.readLine()) != null) { - if (eventMatcher.matches(line, regexpPattern)) { - //build an event from the previous match (held in current map) - LoggingEvent event = buildEvent(); - if (event != null) { - if (passesExpression(event)) { - doPost(event); - } - } - currentMap.putAll(processEvent(eventMatcher.getMatch())); - } else { - //getLogger().debug("line doesn't match pattern - must be ") - //may be an exception or additional message lines - additionalLines.add(line); - } - } - - //process last event if one exists - LoggingEvent event = buildEvent(); - if (event != null) { - if (passesExpression(event)) { - doPost(event); - } - getLogger().debug("no further lines to process in " + fileURL); - } - try { - synchronized (this) { - wait(2000); - } - } catch (InterruptedException ie) { - } - } while (tailing); - getLogger().debug("processing " + fileURL + " complete"); - shutdown(); - } - - /** - * Helper method that supports the evaluation of the expression - * - * @param event - * @return true if expression isn't set, or the result of the evaluation otherwise - */ - private boolean passesExpression(LoggingEvent event) { - if (event != null) { - if (expressionRule != null) { - return (expressionRule.evaluate(event)); - } - } - return true; - } - - /** - * Convert the ORO match into a map. - *

    A watchdog is an entity that monitors a source of configuration data. - If the source indicates that the configuration data has been changed, then - the new configuration data is read and the log4j environment is - reconfigured using the new data. - -

    Examples of watchdogs are FileWatchdog and SocketWatchdog. FileWatchdog - monitors a configuration file for updates, using the updated file to - reconfigure log4j. SocketWatchdog monitors a socket port, using the data - stream from the socket to reconfigure log4j. - -

    Watchdogs are implemented as instances of the Plugin interface and can - be started and stopped like any other Plugin object. - -

    Watchdogs are not specific to any Configurator class. Any Configurator - can be used with any Watchdog. When reconfiguring, the Watchdog should - create a new instance of the defined Configurator class and call the - appropriate Configurator method to reconfigure the log4j environment. - - @author Mark Womack - @since 1.3 -*/ -public interface Watchdog extends Plugin { - - /** - * Sets the Configurator class used for reconfiguration. - * - * @param configuratorClassName Fully qualified class name for - * Configurator class. - */ - public void setConfigurator(String configuratorClassName); - - /** - * Returns the configurator class used for reconfiguration. - * - * @return Fully qualified class name for Configurator class. - */ - public String getConfigurator(); - - /** - * Called to reconfigure the log4j environment when the monitored data - * source has been updated. - * - * @return True if reconfiguration was without errors - */ - public boolean reconfigure(); - -} diff --git a/src/main/java/org/apache/log4j/watchdog/WatchdogSkeleton.java b/src/main/java/org/apache/log4j/watchdog/WatchdogSkeleton.java deleted file mode 100644 index 95b1f91dae..0000000000 --- a/src/main/java/org/apache/log4j/watchdog/WatchdogSkeleton.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.watchdog; - - -import org.apache.log4j.PropertyConfigurator; -import org.apache.log4j.config.ConfiguratorBase; -import org.apache.log4j.spi.Configurator; -import org.apache.log4j.spi.ConfiguratorEx; -import org.apache.log4j.plugins.PluginSkeleton; -import org.apache.log4j.helpers.OptionConverter; - -import java.net.URL; -import java.io.InputStream; -import java.util.List; - -/** - Implements the required interface for Watchdog objects. - -

    This class provides an implementation of the Watchdog interface that - forms the base class used for specific Watchdog classes implemented in the - log4j framework. Using this class for all Watchdog implementations is not - required. Developers may choose to implement their own version of the - Watchdog interface (which extends the base Plugin interface) if they so - choose. - -

    This implementation provides two helper methods, reconfigureByURL and - reconfigureByInputStream. Either of these methods can be called from the - implemented reconfigure method, as required by the specific type of data - source being monitored. The reconfigureByURL method is meant for sources - that can be described by a URL (ie file, url). The rconfigureByInputStream - method is meant for sources where onl a stream of data is available - (ie socket). - -

    Subclasses of this implementation are required to implement their own - version of the abstract reconfigure method. - - @author Mark Womack - @since 1.3 -*/ -public abstract class WatchdogSkeleton -extends PluginSkeleton implements Watchdog { - - protected String configuratorClassName; - - /** - * Sets the Configurator class used for reconfiguration. - * - * @param configuratorClassName Fully qualified class name for Configurator - * class. - */ - public void setConfigurator(String configuratorClassName) { - this.configuratorClassName = configuratorClassName; - } - - /** - * Returns the configurator class used for reconfiguration. - * - * @return Fully qualified class name for Configurator class. - */ - public String getConfigurator() { - return configuratorClassName; - } - - /** - * Called to reconfigure the log4j environment when the monitored data - * source has been updated. Must be implemented by subclasses. - */ - public abstract boolean reconfigure(); - - /** - * Helper method to get an instance of the configurator class. - * - * @return An instance of the Configurator class to use - * for reconfiguration. - */ - protected Configurator getConfiguratorInstance() { - // create an instance of the configurator class - Configurator configurator; - - // if we were configured with a configurator class name, use it - if (configuratorClassName != null) { - configurator = (Configurator) OptionConverter.instantiateByClassName( - configuratorClassName, Configurator.class, null); - } - // otherwise, default to PropertyConfigurator - else { - configurator = new PropertyConfigurator(); - } - - return configurator; - } - - /** - * Helper method to reconfigure using a URL. - * The input parameter, configurationURL, should be a URL pointing to - * the configuration data in a format expected by the configurator. - * - * @param srcURL The url that contains the data to be used for - * reconfiguration. - * @return True if the reconfiguration was without error - */ - protected boolean reconfigureByURL(URL srcURL) { - if (this.getLogger().isDebugEnabled()) { - this.getLogger().debug("watchdog \"{}\" reconfiguring from url: {}", - this.getName(), srcURL); - } - - // create an instance of the configurator class - Configurator configurator = getConfiguratorInstance(); - if (configurator == null) { - getLogger().error( - "watchdog \"{}\" could not create configurator, ignoring new configuration settings", - this.getName()); - return false; - } - - configurator.doConfigure(srcURL, this.getLoggerRepository()); - return configure(configurator); - } - - /** - * Helper method to reconfigure using an InputStream. - * - * @param stream The stream of data to be used for reconfiguration. - * @return True if the reconfiguration was without error - */ - protected boolean reconfigureByStream(InputStream stream) { - if (this.getLogger().isDebugEnabled()) { - this.getLogger().debug("watchdog \"{}\" reconfiguring by stream", - this.getName()); - } - - // create an instance of the configurator class - Configurator configurator = getConfiguratorInstance(); - - if (configurator instanceof ConfiguratorEx) { - ConfiguratorEx configuratorEx = (ConfiguratorEx)configurator; - configuratorEx.doConfigure(stream, this.getLoggerRepository()); - return configure(configurator); - } else { - getLogger().error( - "watchdog \"{}\" could not create configurator, configurator class is not of type ConfiguratorEx", - this.getName()); - return false; - } - - } - - private boolean configure(Configurator configurator) { - if (configurator instanceof ConfiguratorBase) { - ConfiguratorBase baseConfigurator = (ConfiguratorBase)configurator; - List errorList = baseConfigurator.getErrorList(); - if (errorList.size() != 0) { - getLogger().error("errors reported during reconfiguration: "); - for (int x = 0; x < errorList.size(); x++) { - getLogger().debug("error " + x + ": " + errorList.get(x)); - } - return false; - } - } - return true; - } -} diff --git a/src/main/java/org/apache/log4j/xml/.cvsignore b/src/main/java/org/apache/log4j/xml/.cvsignore deleted file mode 100644 index f590ca415d..0000000000 --- a/src/main/java/org/apache/log4j/xml/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -doc-files \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/xml/DOMConfigurator.java b/src/main/java/org/apache/log4j/xml/DOMConfigurator.java index cb5987c82c..d3b664468f 100644 --- a/src/main/java/org/apache/log4j/xml/DOMConfigurator.java +++ b/src/main/java/org/apache/log4j/xml/DOMConfigurator.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,36 +17,57 @@ package org.apache.log4j.xml; +import org.apache.log4j.Appender; +import org.apache.log4j.Layout; +import org.apache.log4j.Level; import org.apache.log4j.LogManager; -import org.apache.log4j.joran.JoranConfigurator; +import org.apache.log4j.Logger; +import org.apache.log4j.config.PropertySetter; +import org.apache.log4j.helpers.FileWatchdog; +import org.apache.log4j.helpers.Loader; +import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.helpers.OptionConverter; +import org.apache.log4j.or.RendererMap; +import org.apache.log4j.spi.AppenderAttachable; +import org.apache.log4j.spi.Configurator; +import org.apache.log4j.spi.ErrorHandler; +import org.apache.log4j.spi.Filter; +import org.apache.log4j.spi.LoggerFactory; import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggerRepositoryEx; -import org.apache.log4j.plugins.PluginRegistry; -import org.apache.log4j.watchdog.FileWatchdog; - +import org.apache.log4j.spi.RendererSupport; +import org.apache.log4j.spi.ThrowableRenderer; +import org.apache.log4j.spi.ThrowableRendererSupport; +import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; - +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; import org.xml.sax.SAXException; -import org.xml.sax.helpers.AttributesImpl; -import org.xml.sax.helpers.DefaultHandler; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.FactoryConfigurationError; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InterruptedIOException; +import java.io.Reader; +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; import java.net.URL; -import java.net.MalformedURLException; - -import javax.xml.parsers.SAXParser; - +import java.net.URLConnection; +import java.util.Hashtable; +import java.util.Properties; // Contributors: Mark Womack -// Arun Katkere -// Curt Arnold +// Arun Katkere /** Use this class to initialize the log4j environment using a DOM tree.

    The DTD is specified in log4j.dtd. + href="doc-files/log4j.dtd">log4j.dtd.

    Sometimes it is useful to see how log4j is reading configuration files. You can enable log4j internal logging by defining the @@ -60,181 +81,1049 @@

    There are sample XML files included in the package. - + @author Christopher Taylor @author Ceki Gülcü @author Anders Kristensen - @deprecated Replaced by the much more flexible {@link org.apache.log4j.joran.JoranConfigurator}. + @since 0.8.3 */ -public class DOMConfigurator extends JoranConfigurator { +public class DOMConfigurator implements Configurator { + + static final String CONFIGURATION_TAG = "log4j:configuration"; + static final String OLD_CONFIGURATION_TAG = "configuration"; + static final String RENDERER_TAG = "renderer"; + private static final String THROWABLE_RENDERER_TAG = "throwableRenderer"; + static final String APPENDER_TAG = "appender"; + static final String APPENDER_REF_TAG = "appender-ref"; + static final String PARAM_TAG = "param"; + static final String LAYOUT_TAG = "layout"; + static final String CATEGORY = "category"; + static final String LOGGER = "logger"; + static final String LOGGER_REF = "logger-ref"; + static final String CATEGORY_FACTORY_TAG = "categoryFactory"; + static final String LOGGER_FACTORY_TAG = "loggerFactory"; + static final String NAME_ATTR = "name"; + static final String CLASS_ATTR = "class"; + static final String VALUE_ATTR = "value"; + static final String ROOT_TAG = "root"; + static final String ROOT_REF = "root-ref"; + static final String LEVEL_TAG = "level"; + static final String PRIORITY_TAG = "priority"; + static final String FILTER_TAG = "filter"; + static final String ERROR_HANDLER_TAG = "errorHandler"; + static final String REF_ATTR = "ref"; + static final String ADDITIVITY_ATTR = "additivity"; + static final String THRESHOLD_ATTR = "threshold"; + static final String CONFIG_DEBUG_ATTR = "configDebug"; + static final String INTERNAL_DEBUG_ATTR = "debug"; + private static final String RESET_ATTR = "reset"; + static final String RENDERING_CLASS_ATTR = "renderingClass"; + static final String RENDERED_CLASS_ATTR = "renderedClass"; + + static final String EMPTY_STR = ""; + static final Class[] ONE_STRING_PARAM = new Class[] {String.class}; + + final static String dbfKey = "javax.xml.parsers.DocumentBuilderFactory"; - private static Object watchdogLock = new Object(); - private static FileWatchdog fileWatchdog = null; - public static void configure(String file) { - JoranConfigurator joran = new JoranConfigurator(); - joran.doConfigure(file, LogManager.getLoggerRepository()); - } + // key: appenderName, value: appender + Hashtable appenderBag; - public static void configure(URL url) { - JoranConfigurator joran = new JoranConfigurator(); - joran.doConfigure(url, LogManager.getLoggerRepository()); - } + Properties props; + LoggerRepository repository; + + protected LoggerFactory catFactory = null; /** - * Configure log4j using a configuration element. - * @param element element, may not be null. + No argument constructor. */ - public static void configure(final Element element) { - DOMConfigurator configurator = new DOMConfigurator(); - configurator.doConfigure(element, LogManager.getLoggerRepository()); + public + DOMConfigurator () { + appenderBag = new Hashtable(); } /** - * Configure by taking in an DOM element. - * @param element configuration element, may not be null. - * @param repository logger repository. + Used internally to parse appenders by IDREF name. */ - public void doConfigure( - final Element element, final LoggerRepository repository) { - ParseAction action = new DOMElementParseAction(element); - doConfigure(action, repository); + protected + Appender findAppenderByName(Document doc, String appenderName) { + Appender appender = (Appender) appenderBag.get(appenderName); + + if(appender != null) { + return appender; + } else { + // Doesn't work on DOM Level 1 : + // Element element = doc.getElementById(appenderName); + + // Endre's hack: + Element element = null; + NodeList list = doc.getElementsByTagName("appender"); + for (int t=0; t < list.getLength(); t++) { + Node node = list.item(t); + NamedNodeMap map= node.getAttributes(); + Node attrNode = map.getNamedItem("name"); + if (appenderName.equals(attrNode.getNodeValue())) { + element = (Element) node; + break; + } + } + // Hack finished. + + if(element == null) { + LogLog.error("No appender named ["+appenderName+"] could be found."); + return null; + } else { + appender = parseAppender(element); + if (appender != null) { + appenderBag.put(appenderName, appender); + } + return appender; + } + } + } + /** + Used internally to parse appenders by IDREF element. + */ + protected + Appender findAppenderByReference(Element appenderRef) { + String appenderName = subst(appenderRef.getAttribute(REF_ATTR)); + Document doc = appenderRef.getOwnerDocument(); + return findAppenderByName(doc, appenderName); + } + + /** + * Delegates unrecognized content to created instance if + * it supports UnrecognizedElementParser. + * @since 1.2.15 + * @param instance instance, may be null. + * @param element element, may not be null. + * @param props properties + * @throws IOException thrown if configuration of owner object + * should be abandoned. + */ + private static void parseUnrecognizedElement(final Object instance, + final Element element, + final Properties props) throws Exception { + boolean recognized = false; + if (instance instanceof UnrecognizedElementHandler) { + recognized = ((UnrecognizedElementHandler) instance).parseUnrecognizedElement( + element, props); + } + if (!recognized) { + LogLog.warn("Unrecognized element " + element.getNodeName()); + } + } + + /** + * Delegates unrecognized content to created instance if + * it supports UnrecognizedElementParser and catches and + * logs any exception. + * @since 1.2.15 + * @param instance instance, may be null. + * @param element element, may not be null. + * @param props properties + */ + private static void quietParseUnrecognizedElement(final Object instance, + final Element element, + final Properties props) { + try { + parseUnrecognizedElement(instance, element, props); + } catch (Exception ex) { + if (ex instanceof InterruptedException || ex instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.error("Error in extension content: ", ex); + } + } + + /** + Used internally to parse an appender element. + */ + protected + Appender parseAppender (Element appenderElement) { + String className = subst(appenderElement.getAttribute(CLASS_ATTR)); + LogLog.debug("Class name: [" + className+']'); + try { + Object instance = Loader.loadClass(className).newInstance(); + Appender appender = (Appender)instance; + PropertySetter propSetter = new PropertySetter(appender); + + appender.setName(subst(appenderElement.getAttribute(NAME_ATTR))); + + NodeList children = appenderElement.getChildNodes(); + final int length = children.getLength(); + + for (int loop = 0; loop < length; loop++) { + Node currentNode = children.item(loop); + + /* We're only interested in Elements */ + if (currentNode.getNodeType() == Node.ELEMENT_NODE) { + Element currentElement = (Element)currentNode; + + // Parse appender parameters + if (currentElement.getTagName().equals(PARAM_TAG)) { + setParameter(currentElement, propSetter); + } + // Set appender layout + else if (currentElement.getTagName().equals(LAYOUT_TAG)) { + appender.setLayout(parseLayout(currentElement)); + } + // Add filters + else if (currentElement.getTagName().equals(FILTER_TAG)) { + parseFilters(currentElement, appender); + } + else if (currentElement.getTagName().equals(ERROR_HANDLER_TAG)) { + parseErrorHandler(currentElement, appender); + } + else if (currentElement.getTagName().equals(APPENDER_REF_TAG)) { + String refName = subst(currentElement.getAttribute(REF_ATTR)); + if(appender instanceof AppenderAttachable) { + AppenderAttachable aa = (AppenderAttachable) appender; + LogLog.debug("Attaching appender named ["+ refName+ + "] to appender named ["+ appender.getName()+"]."); + aa.addAppender(findAppenderByReference(currentElement)); + } else { + LogLog.error("Requesting attachment of appender named ["+ + refName+ "] to appender named ["+ appender.getName()+ + "] which does not implement org.apache.log4j.spi.AppenderAttachable."); + } + } else { + parseUnrecognizedElement(instance, currentElement, props); + } + } + } + propSetter.activate(); + return appender; + } + /* Yes, it's ugly. But all of these exceptions point to the same + problem: we can't create an Appender */ + catch (Exception oops) { + if (oops instanceof InterruptedException || oops instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.error("Could not create an Appender. Reported error follows.", + oops); + return null; + } } /** - Like {@link #configureAndWatch(String, long)} except that the - default delay of 60 seconds is used. + Used internally to parse an {@link ErrorHandler} element. + */ + protected + void parseErrorHandler(Element element, Appender appender) { + ErrorHandler eh = (ErrorHandler) OptionConverter.instantiateByClassName( + subst(element.getAttribute(CLASS_ATTR)), + org.apache.log4j.spi.ErrorHandler.class, + null); - @deprecated Use org.apache.log4j.watchdog.FileWatchdog directly. + if(eh != null) { + eh.setAppender(appender); + + PropertySetter propSetter = new PropertySetter(eh); + NodeList children = element.getChildNodes(); + final int length = children.getLength(); + + for (int loop = 0; loop < length; loop++) { + Node currentNode = children.item(loop); + if (currentNode.getNodeType() == Node.ELEMENT_NODE) { + Element currentElement = (Element) currentNode; + String tagName = currentElement.getTagName(); + if(tagName.equals(PARAM_TAG)) { + setParameter(currentElement, propSetter); + } else if(tagName.equals(APPENDER_REF_TAG)) { + eh.setBackupAppender(findAppenderByReference(currentElement)); + } else if(tagName.equals(LOGGER_REF)) { + String loggerName = currentElement.getAttribute(REF_ATTR); + Logger logger = (catFactory == null) ? repository.getLogger(loggerName) + : repository.getLogger(loggerName, catFactory); + eh.setLogger(logger); + } else if(tagName.equals(ROOT_REF)) { + Logger root = repository.getRootLogger(); + eh.setLogger(root); + } else { + quietParseUnrecognizedElement(eh, currentElement, props); + } + } + } + propSetter.activate(); + appender.setErrorHandler(eh); + } + } + + /** + Used internally to parse a filter element. + */ + protected + void parseFilters(Element element, Appender appender) { + String clazz = subst(element.getAttribute(CLASS_ATTR)); + Filter filter = (Filter) OptionConverter.instantiateByClassName(clazz, + Filter.class, null); - @param configFilename A log4j configuration file in XML format. + if(filter != null) { + PropertySetter propSetter = new PropertySetter(filter); + NodeList children = element.getChildNodes(); + final int length = children.getLength(); + + for (int loop = 0; loop < length; loop++) { + Node currentNode = children.item(loop); + if (currentNode.getNodeType() == Node.ELEMENT_NODE) { + Element currentElement = (Element) currentNode; + String tagName = currentElement.getTagName(); + if(tagName.equals(PARAM_TAG)) { + setParameter(currentElement, propSetter); + } else { + quietParseUnrecognizedElement(filter, currentElement, props); + } + } + } + propSetter.activate(); + LogLog.debug("Adding filter of type ["+filter.getClass() + +"] to appender named ["+appender.getName()+"]."); + appender.addFilter(filter); + } + } + + /** + Used internally to parse an category element. + */ + protected + void parseCategory (Element loggerElement) { + // Create a new org.apache.log4j.Category object from the element. + String catName = subst(loggerElement.getAttribute(NAME_ATTR)); + + Logger cat; + + String className = subst(loggerElement.getAttribute(CLASS_ATTR)); + + + if(EMPTY_STR.equals(className)) { + LogLog.debug("Retreiving an instance of org.apache.log4j.Logger."); + cat = (catFactory == null) ? repository.getLogger(catName) : repository.getLogger(catName, catFactory); + } + else { + LogLog.debug("Desired logger sub-class: ["+className+']'); + try { + Class clazz = Loader.loadClass(className); + Method getInstanceMethod = clazz.getMethod("getLogger", + ONE_STRING_PARAM); + cat = (Logger) getInstanceMethod.invoke(null, new Object[] {catName}); + } catch (InvocationTargetException oops) { + if (oops.getTargetException() instanceof InterruptedException + || oops.getTargetException() instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.error("Could not retrieve category ["+catName+ + "]. Reported error follows.", oops); + return; + } catch (Exception oops) { + LogLog.error("Could not retrieve category ["+catName+ + "]. Reported error follows.", oops); + return; + } + } + + // Setting up a category needs to be an atomic operation, in order + // to protect potential log operations while category + // configuration is in progress. + synchronized(cat) { + boolean additivity = OptionConverter.toBoolean( + subst(loggerElement.getAttribute(ADDITIVITY_ATTR)), + true); + LogLog.debug("Setting ["+cat.getName()+"] additivity to ["+additivity+"]."); + cat.setAdditivity(additivity); + parseChildrenOfLoggerElement(loggerElement, cat, false); + } + } + + + /** + Used internally to parse the category factory element. */ - static public void configureAndWatch(String configFilename) { - configureAndWatch(configFilename, 60000); + protected + void parseCategoryFactory(Element factoryElement) { + String className = subst(factoryElement.getAttribute(CLASS_ATTR)); + + if(EMPTY_STR.equals(className)) { + LogLog.error("Category Factory tag " + CLASS_ATTR + " attribute not found."); + LogLog.debug("No Category Factory configured."); + } + else { + LogLog.debug("Desired category factory: ["+className+']'); + Object factory = OptionConverter.instantiateByClassName(className, + LoggerFactory.class, + null); + if (factory instanceof LoggerFactory) { + catFactory = (LoggerFactory) factory; + } else { + LogLog.error("Category Factory class " + className + " does not implement org.apache.log4j.LoggerFactory"); + } + PropertySetter propSetter = new PropertySetter(factory); + + Element currentElement = null; + Node currentNode = null; + NodeList children = factoryElement.getChildNodes(); + final int length = children.getLength(); + + for (int loop=0; loop < length; loop++) { + currentNode = children.item(loop); + if (currentNode.getNodeType() == Node.ELEMENT_NODE) { + currentElement = (Element)currentNode; + if (currentElement.getTagName().equals(PARAM_TAG)) { + setParameter(currentElement, propSetter); + } else { + quietParseUnrecognizedElement(factory, currentElement, props); + } + } + } + } } + /** - Read the configuration file configFilename if it - exists. Moreover, a thread will be created that will periodically - check if configFilename has been created or - modified. The period is determined by the delay - argument. If a change or file creation is detected, then - configFilename is read to configure log4j. + Used internally to parse the roor category element. + */ + protected + void parseRoot (Element rootElement) { + Logger root = repository.getRootLogger(); + // category configuration needs to be atomic + synchronized(root) { + parseChildrenOfLoggerElement(rootElement, root, true); + } + } - @deprecated Use org.apache.log4j.watchdog.FileWatchdog directly. - - @param configFilename A log4j configuration file in XML format. - @param delay The delay in milliseconds to wait between each check. + + /** + Used internally to parse the children of a category element. */ - static public void configureAndWatch(String configFilename, long delay) { - synchronized(watchdogLock) { - PluginRegistry pluginRegistry = - ((LoggerRepositoryEx)LogManager.getLoggerRepository()).getPluginRegistry(); - - // stop existing watchdog - if (fileWatchdog != null) { - pluginRegistry.stopPlugin(fileWatchdog.getName()); - fileWatchdog = null; + protected + void parseChildrenOfLoggerElement(Element catElement, + Logger cat, boolean isRoot) { + + PropertySetter propSetter = new PropertySetter(cat); + + // Remove all existing appenders from cat. They will be + // reconstructed if need be. + cat.removeAllAppenders(); + + + NodeList children = catElement.getChildNodes(); + final int length = children.getLength(); + + for (int loop = 0; loop < length; loop++) { + Node currentNode = children.item(loop); + + if (currentNode.getNodeType() == Node.ELEMENT_NODE) { + Element currentElement = (Element) currentNode; + String tagName = currentElement.getTagName(); + + if (tagName.equals(APPENDER_REF_TAG)) { + Element appenderRef = (Element) currentNode; + Appender appender = findAppenderByReference(appenderRef); + String refName = subst(appenderRef.getAttribute(REF_ATTR)); + if(appender != null) { + LogLog.debug("Adding appender named ["+ refName+ + "] to category ["+cat.getName()+"]."); + } else { + LogLog.debug("Appender named ["+ refName + "] not found."); + } + + cat.addAppender(appender); + + } else if(tagName.equals(LEVEL_TAG)) { + parseLevel(currentElement, cat, isRoot); + } else if(tagName.equals(PRIORITY_TAG)) { + parseLevel(currentElement, cat, isRoot); + } else if(tagName.equals(PARAM_TAG)) { + setParameter(currentElement, propSetter); + } else { + quietParseUnrecognizedElement(cat, currentElement, props); + } } + } + propSetter.activate(); + } + + /** + Used internally to parse a layout element. + */ + protected + Layout parseLayout (Element layout_element) { + String className = subst(layout_element.getAttribute(CLASS_ATTR)); + LogLog.debug("Parsing layout of class: \""+className+"\""); + try { + Object instance = Loader.loadClass(className).newInstance(); + Layout layout = (Layout)instance; + PropertySetter propSetter = new PropertySetter(layout); - // create the watchdog - fileWatchdog = new FileWatchdog(); - fileWatchdog.setName("DOMConfigurator.FileWatchdog"); - fileWatchdog.setConfigurator(DOMConfigurator.class.getName()); - fileWatchdog.setFile(configFilename); - fileWatchdog.setInterval(delay); - fileWatchdog.setInitialConfigure(true); + NodeList params = layout_element.getChildNodes(); + final int length = params.getLength(); + + for (int loop = 0; loop < length; loop++) { + Node currentNode = params.item(loop); + if (currentNode.getNodeType() == Node.ELEMENT_NODE) { + Element currentElement = (Element) currentNode; + String tagName = currentElement.getTagName(); + if(tagName.equals(PARAM_TAG)) { + setParameter(currentElement, propSetter); + } else { + parseUnrecognizedElement(instance, currentElement, props); + } + } + } - // register and start the watchdog - pluginRegistry.addPlugin(fileWatchdog); - fileWatchdog.activateOptions(); + propSetter.activate(); + return layout; + } + catch (Exception oops) { + if (oops instanceof InterruptedException || oops instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.error("Could not create the Layout. Reported error follows.", + oops); + return null; } } - - /** - * Class that "parses" a DOM element by replaying the - * corresponding SAX events. - */ - private static class DOMElementParseAction implements ParseAction { - private final Element element; - private final AttributesImpl attributes = new AttributesImpl(); - /** - * Creates an DOMElementParser. - * @param element configuration element. - */ - public DOMElementParseAction(final Element element) { - this.element = element; + protected + void parseRenderer(Element element) { + String renderingClass = subst(element.getAttribute(RENDERING_CLASS_ATTR)); + String renderedClass = subst(element.getAttribute(RENDERED_CLASS_ATTR)); + if(repository instanceof RendererSupport) { + RendererMap.addRenderer((RendererSupport) repository, renderedClass, + renderingClass); } + } /** - * Generates the SAX events corresponding to the document element. - * @param parser SAX parser, ignored. - * @param handler content receiver, may not be null. - * @throws SAXException thrown on content or handling exception. + * Parses throwable renderer. + * @param element throwableRenderer element. + * @return configured throwable renderer. + * @since 1.2.16. */ - public void parse(final SAXParser parser, final DefaultHandler handler) - throws SAXException { - handler.startDocument(); - replay(element, handler); - handler.endDocument(); + protected ThrowableRenderer parseThrowableRenderer(final Element element) { + String className = subst(element.getAttribute(CLASS_ATTR)); + LogLog.debug("Parsing throwableRenderer of class: \""+className+"\""); + try { + Object instance = Loader.loadClass(className).newInstance(); + ThrowableRenderer tr = (ThrowableRenderer)instance; + PropertySetter propSetter = new PropertySetter(tr); + + NodeList params = element.getChildNodes(); + final int length = params.getLength(); + + for (int loop = 0; loop < length; loop++) { + Node currentNode = params.item(loop); + if (currentNode.getNodeType() == Node.ELEMENT_NODE) { + Element currentElement = (Element) currentNode; + String tagName = currentElement.getTagName(); + if(tagName.equals(PARAM_TAG)) { + setParameter(currentElement, propSetter); + } else { + parseUnrecognizedElement(instance, currentElement, props); + } + } + } + + propSetter.activate(); + return tr; + } + catch (Exception oops) { + if (oops instanceof InterruptedException || oops instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.error("Could not create the ThrowableRenderer. Reported error follows.", + oops); + return null; + } } - /** - * Generates the SAX events corresponding to the element. - * - * @param element element, may not be null. - * @param handler content handler, may not be null. - * @throws SAXException if content error. - */ - private void replay(final Element element, final DefaultHandler handler) - throws SAXException { - String localName = element.getLocalName(); - String nsURI = element.getNamespaceURI(); - String qName = element.getNodeName(); + /** + Used internally to parse a level element. + */ + protected + void parseLevel(Element element, Logger logger, boolean isRoot) { + String catName = logger.getName(); + if(isRoot) { + catName = "root"; + } - if (localName == null) { - localName = qName; + String priStr = subst(element.getAttribute(VALUE_ATTR)); + LogLog.debug("Level value for "+catName+" is ["+priStr+"]."); + + if(INHERITED.equalsIgnoreCase(priStr) || NULL.equalsIgnoreCase(priStr)) { + if(isRoot) { + LogLog.error("Root level cannot be inherited. Ignoring directive."); + } else { + logger.setLevel(null); + } + } else { + String className = subst(element.getAttribute(CLASS_ATTR)); + if(EMPTY_STR.equals(className)) { + logger.setLevel(OptionConverter.toLevel(priStr, Level.DEBUG)); + } else { + LogLog.debug("Desired Level sub-class: ["+className+']'); + try { + Class clazz = Loader.loadClass(className); + Method toLevelMethod = clazz.getMethod("toLevel", + ONE_STRING_PARAM); + Level pri = (Level) toLevelMethod.invoke(null, + new Object[] {priStr}); + logger.setLevel(pri); + } catch (Exception oops) { + if (oops instanceof InterruptedException || oops instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.error("Could not create level ["+priStr+ + "]. Reported error follows.", oops); + return; + } } + } + LogLog.debug(catName + " level set to " + logger.getLevel()); + } + + protected + void setParameter(Element elem, PropertySetter propSetter) { + String name = subst(elem.getAttribute(NAME_ATTR)); + String value = (elem.getAttribute(VALUE_ATTR)); + value = subst(OptionConverter.convertSpecialChars(value)); + propSetter.setProperty(name, value); + } + + + /** + Configure log4j using a configuration element as + defined in the log4j.dtd. + + */ + static + public + void configure (Element element) { + DOMConfigurator configurator = new DOMConfigurator(); + configurator.doConfigure(element, LogManager.getLoggerRepository()); + } + + /** + Like {@link #configureAndWatch(String, long)} except that the + default delay as defined by {@link FileWatchdog#DEFAULT_DELAY} is + used. + + @param configFilename A log4j configuration file in XML format. + + */ + static + public + void configureAndWatch(String configFilename) { + configureAndWatch(configFilename, FileWatchdog.DEFAULT_DELAY); + } + + /** + Read the configuration file configFilename if it + exists. Moreover, a thread will be created that will periodically + check if configFilename has been created or + modified. The period is determined by the delay + argument. If a change or file creation is detected, then + configFilename is read to configure log4j. + + @param configFilename A log4j configuration file in XML format. + @param delay The delay in milliseconds to wait between each check. + */ + static + public + void configureAndWatch(String configFilename, long delay) { + XMLWatchdog xdog = new XMLWatchdog(configFilename); + xdog.setDelay(delay); + xdog.start(); + } + + private interface ParseAction { + Document parse(final DocumentBuilder parser) throws SAXException, IOException; + } + + + public + void doConfigure(final String filename, LoggerRepository repository) { + ParseAction action = new ParseAction() { + public Document parse(final DocumentBuilder parser) throws SAXException, IOException { + return parser.parse(new File(filename)); + } + public String toString() { + return "file [" + filename + "]"; + } + }; + doConfigure(action, repository); + } + + + public + void doConfigure(final URL url, LoggerRepository repository) { + ParseAction action = new ParseAction() { + public Document parse(final DocumentBuilder parser) throws SAXException, IOException { + URLConnection uConn = url.openConnection(); + uConn.setUseCaches(false); + InputStream stream = uConn.getInputStream(); + try { + InputSource src = new InputSource(stream); + src.setSystemId(url.toString()); + return parser.parse(src); + } finally { + stream.close(); + } + } + public String toString() { + return "url [" + url.toString() + "]"; + } + }; + doConfigure(action, repository); + } - attributes.clear(); + /** + Configure log4j by reading in a log4j.dtd compliant XML + configuration file. + + */ + public + void doConfigure(final InputStream inputStream, LoggerRepository repository) + throws FactoryConfigurationError { + ParseAction action = new ParseAction() { + public Document parse(final DocumentBuilder parser) throws SAXException, IOException { + InputSource inputSource = new InputSource(inputStream); + inputSource.setSystemId("dummy://log4j.dtd"); + return parser.parse(inputSource); + } + public String toString() { + return "input stream [" + inputStream.toString() + "]"; + } + }; + doConfigure(action, repository); + } - NamedNodeMap attrNodes = element.getAttributes(); - int attrCount = attrNodes.getLength(); - Node attr; + /** + Configure log4j by reading in a log4j.dtd compliant XML + configuration file. - for (int i = 0; i < attrCount; i++) { - attr = attrNodes.item(i); + */ + public + void doConfigure(final Reader reader, LoggerRepository repository) + throws FactoryConfigurationError { + ParseAction action = new ParseAction() { + public Document parse(final DocumentBuilder parser) throws SAXException, IOException { + InputSource inputSource = new InputSource(reader); + inputSource.setSystemId("dummy://log4j.dtd"); + return parser.parse(inputSource); + } + public String toString() { + return "reader [" + reader.toString() + "]"; + } + }; + doConfigure(action, repository); + } - String attrQName = attr.getNodeName(); - String attrName = attr.getLocalName(); + /** + Configure log4j by reading in a log4j.dtd compliant XML + configuration file. - if (attrName == null) { - attrName = attrQName; + */ + protected + void doConfigure(final InputSource inputSource, LoggerRepository repository) + throws FactoryConfigurationError { + if (inputSource.getSystemId() == null) { + inputSource.setSystemId("dummy://log4j.dtd"); + } + ParseAction action = new ParseAction() { + public Document parse(final DocumentBuilder parser) throws SAXException, IOException { + return parser.parse(inputSource); + } + public String toString() { + return "input source [" + inputSource.toString() + "]"; + } + }; + doConfigure(action, repository); + } + + + private final void doConfigure(final ParseAction action, final LoggerRepository repository) + throws FactoryConfigurationError { + DocumentBuilderFactory dbf = null; + this.repository = repository; + try { + LogLog.debug("System property is :"+ + OptionConverter.getSystemProperty(dbfKey, + null)); + dbf = DocumentBuilderFactory.newInstance(); + LogLog.debug("Standard DocumentBuilderFactory search succeded."); + LogLog.debug("DocumentBuilderFactory is: "+dbf.getClass().getName()); + } catch(FactoryConfigurationError fce) { + Exception e = fce.getException(); + LogLog.debug("Could not instantiate a DocumentBuilderFactory.", e); + throw fce; + } + + try { + dbf.setValidating(true); + + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + + docBuilder.setErrorHandler(new SAXErrorHandler()); + docBuilder.setEntityResolver(new Log4jEntityResolver()); + + Document doc = action.parse(docBuilder); + parse(doc.getDocumentElement()); + } catch (Exception e) { + if (e instanceof InterruptedException || e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); } + // I know this is miserable... + LogLog.error("Could not parse "+ action.toString() + ".", e); + } + } - String attrNsURI = attr.getNamespaceURI(); - String attrValue = attr.getNodeValue(); - attributes.addAttribute( - attrNsURI, attrName, attrQName, "#PCDATA", attrValue); + /** + Configure by taking in an DOM element. + */ + public void doConfigure(Element element, LoggerRepository repository) { + this.repository = repository; + parse(element); + } + + + /** + A static version of {@link #doConfigure(String, LoggerRepository)}. */ + static + public + void configure(String filename) throws FactoryConfigurationError { + new DOMConfigurator().doConfigure(filename, + LogManager.getLoggerRepository()); + } + + /** + A static version of {@link #doConfigure(URL, LoggerRepository)}. + */ + static + public + void configure(URL url) throws FactoryConfigurationError { + new DOMConfigurator().doConfigure(url, LogManager.getLoggerRepository()); + } + + /** + Used internally to configure the log4j framework by parsing a DOM + tree of XML elements based on log4j.dtd. + + */ + protected + void parse(Element element) { + + String rootElementName = element.getTagName(); + + if (!rootElementName.equals(CONFIGURATION_TAG)) { + if(rootElementName.equals(OLD_CONFIGURATION_TAG)) { + LogLog.warn("The <"+OLD_CONFIGURATION_TAG+ + "> element has been deprecated."); + LogLog.warn("Use the <"+CONFIGURATION_TAG+"> element instead."); + } else { + LogLog.error("DOM element is - not a <"+CONFIGURATION_TAG+"> element."); + return; } + } + + + String debugAttrib = subst(element.getAttribute(INTERNAL_DEBUG_ATTR)); + + LogLog.debug("debug attribute= \"" + debugAttrib +"\"."); + // if the log4j.dtd is not specified in the XML file, then the + // "debug" attribute is returned as the empty string. + if(!debugAttrib.equals("") && !debugAttrib.equals("null")) { + LogLog.setInternalDebugging(OptionConverter.toBoolean(debugAttrib, true)); + } else { + LogLog.debug("Ignoring " + INTERNAL_DEBUG_ATTR + " attribute."); + } + + // + // reset repository before configuration if reset="true" + // on configuration element. + // + String resetAttrib = subst(element.getAttribute(RESET_ATTR)); + LogLog.debug("reset attribute= \"" + resetAttrib +"\"."); + if(!("".equals(resetAttrib))) { + if (OptionConverter.toBoolean(resetAttrib, false)) { + repository.resetConfiguration(); + } + } - handler.startElement(nsURI, localName, qName, attributes); - for ( - Node child = element.getFirstChild(); child != null; - child = child.getNextSibling()) { - // - // Joran only inteprets element content, - // so unnecessary to playback comments, character data, etc. - // - if (child.getNodeType() == Node.ELEMENT_NODE) { - replay((Element) child, handler); + + String confDebug = subst(element.getAttribute(CONFIG_DEBUG_ATTR)); + if(!confDebug.equals("") && !confDebug.equals("null")) { + LogLog.warn("The \""+CONFIG_DEBUG_ATTR+"\" attribute is deprecated."); + LogLog.warn("Use the \""+INTERNAL_DEBUG_ATTR+"\" attribute instead."); + LogLog.setInternalDebugging(OptionConverter.toBoolean(confDebug, true)); + } + + String thresholdStr = subst(element.getAttribute(THRESHOLD_ATTR)); + LogLog.debug("Threshold =\"" + thresholdStr +"\"."); + if(!"".equals(thresholdStr) && !"null".equals(thresholdStr)) { + repository.setThreshold(thresholdStr); + } + + //Hashtable appenderBag = new Hashtable(11); + + /* Building Appender objects, placing them in a local namespace + for future reference */ + + // First configure each category factory under the root element. + // Category factories need to be configured before any of + // categories they support. + // + String tagName = null; + Element currentElement = null; + Node currentNode = null; + NodeList children = element.getChildNodes(); + final int length = children.getLength(); + + for (int loop = 0; loop < length; loop++) { + currentNode = children.item(loop); + if (currentNode.getNodeType() == Node.ELEMENT_NODE) { + currentElement = (Element) currentNode; + tagName = currentElement.getTagName(); + + if (tagName.equals(CATEGORY_FACTORY_TAG) || tagName.equals(LOGGER_FACTORY_TAG)) { + parseCategoryFactory(currentElement); + } + } + } + + for (int loop = 0; loop < length; loop++) { + currentNode = children.item(loop); + if (currentNode.getNodeType() == Node.ELEMENT_NODE) { + currentElement = (Element) currentNode; + tagName = currentElement.getTagName(); + + if (tagName.equals(CATEGORY) || tagName.equals(LOGGER)) { + parseCategory(currentElement); + } else if (tagName.equals(ROOT_TAG)) { + parseRoot(currentElement); + } else if(tagName.equals(RENDERER_TAG)) { + parseRenderer(currentElement); + } else if(tagName.equals(THROWABLE_RENDERER_TAG)) { + if (repository instanceof ThrowableRendererSupport) { + ThrowableRenderer tr = parseThrowableRenderer(currentElement); + if (tr != null) { + ((ThrowableRendererSupport) repository).setThrowableRenderer(tr); + } } + } else if (!(tagName.equals(APPENDER_TAG) + || tagName.equals(CATEGORY_FACTORY_TAG) + || tagName.equals(LOGGER_FACTORY_TAG))) { + quietParseUnrecognizedElement(repository, currentElement, props); + } } + } + } + + + protected + String subst(final String value) { + return subst(value, props); + } + + /** + * Substitutes property value for any references in expression. + * + * @param value value from configuration file, may contain + * literal text, property references or both + * @param props properties. + * @return evaluated expression, may still contain expressions + * if unable to expand. + * @since 1.2.15 + */ + public static String subst(final String value, final Properties props) { + try { + return OptionConverter.substVars(value, props); + } catch (IllegalArgumentException e) { + LogLog.warn("Could not perform variable substitution.", e); + return value; + } + } + + + /** + * Sets a parameter based from configuration file content. + * + * @param elem param element, may not be null. + * @param propSetter property setter, may not be null. + * @param props properties + * @since 1.2.15 + */ + public static void setParameter(final Element elem, + final PropertySetter propSetter, + final Properties props) { + String name = subst(elem.getAttribute("name"), props); + String value = (elem.getAttribute("value")); + value = subst(OptionConverter.convertSpecialChars(value), props); + propSetter.setProperty(name, value); + } + + /** + * Creates an object and processes any nested param elements + * but does not call activateOptions. If the class also supports + * UnrecognizedElementParser, the parseUnrecognizedElement method + * will be call for any child elements other than param. + * + * @param element element, may not be null. + * @param props properties + * @param expectedClass interface or class expected to be implemented + * by created class + * @return created class or null. + * @throws Exception thrown if the contain object should be abandoned. + * @since 1.2.15 + */ + public static Object parseElement(final Element element, + final Properties props, + final Class expectedClass) throws Exception { + String clazz = subst(element.getAttribute("class"), props); + Object instance = OptionConverter.instantiateByClassName(clazz, + expectedClass, null); + + if (instance != null) { + PropertySetter propSetter = new PropertySetter(instance); + NodeList children = element.getChildNodes(); + final int length = children.getLength(); - handler.endElement(nsURI, localName, qName); + for (int loop = 0; loop < length; loop++) { + Node currentNode = children.item(loop); + if (currentNode.getNodeType() == Node.ELEMENT_NODE) { + Element currentElement = (Element) currentNode; + String tagName = currentElement.getTagName(); + if (tagName.equals("param")) { + setParameter(currentElement, propSetter, props); + } else { + parseUnrecognizedElement(instance, currentElement, props); + } + } + } + return instance; + } + return null; } + +} + + +class XMLWatchdog extends FileWatchdog { + + XMLWatchdog(String filename) { + super(filename); + } + + /** + Call {@link DOMConfigurator#configure(String)} with the + filename to reconfigure log4j. */ + public + void doOnChange() { + new DOMConfigurator().doConfigure(filename, + LogManager.getLoggerRepository()); } } diff --git a/src/main/java/org/apache/log4j/xml/Log4jEntityResolver.java b/src/main/java/org/apache/log4j/xml/Log4jEntityResolver.java index c375546aa4..94125a606d 100644 --- a/src/main/java/org/apache/log4j/xml/Log4jEntityResolver.java +++ b/src/main/java/org/apache/log4j/xml/Log4jEntityResolver.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,44 +17,33 @@ package org.apache.log4j.xml; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.log4j.helpers.LogLog; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import java.io.InputStream; - +import java.io.ByteArrayInputStream; /** * An {@link EntityResolver} specifically designed to return * log4j.dtd which is embedded within the log4j jar - * file. + * file. * * @author Paul Austin - * @author Ceki Gulcu (adapted for log4j) * */ public class Log4jEntityResolver implements EntityResolver { - public InputSource resolveEntity(String publicId, String systemId) { - Logger logger = LogManager.getLogger(Log4jEntityResolver.class); + private static final String PUBLIC_ID = "-//APACHE//DTD LOG4J 1.2//EN"; - logger.debug( - "Log4jEntityResolver.resolveEntity({}, {}) called", publicId, systemId); - if (systemId.endsWith("log4j.dtd")) { - //logger.warn("The 'log4j.dtd' is no longer used nor needed."); - //logger.warn("See {}#log4j_dtd for more details.", Constants.CODES_HREF); + public InputSource resolveEntity (String publicId, String systemId) { + if (systemId.endsWith("log4j.dtd") || PUBLIC_ID.equals(publicId)) { Class clazz = getClass(); - InputStream in = - clazz.getResourceAsStream("/org/apache/log4j/xml/log4j.dtd"); - + InputStream in = clazz.getResourceAsStream("/org/apache/log4j/xml/log4j.dtd"); if (in == null) { - logger.error( - "Could not find [log4j.dtd]. Used [{}] class loader in the search.", - clazz.getClassLoader()); - - return null; - } else { - return new InputSource(in); + LogLog.warn("Could not find [log4j.dtd] using [" + clazz.getClassLoader() + + "] class loader, parsed without DTD."); + in = new ByteArrayInputStream(new byte[0]); } + return new InputSource(in); } else { return null; } diff --git a/src/main/java/org/apache/log4j/xml/LogFileXMLReceiver.java b/src/main/java/org/apache/log4j/xml/LogFileXMLReceiver.java deleted file mode 100644 index 3109df7958..0000000000 --- a/src/main/java/org/apache/log4j/xml/LogFileXMLReceiver.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package org.apache.log4j.xml; - -import java.io.BufferedReader; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Collection; -import java.util.Iterator; - -import org.apache.log4j.helpers.Constants; -import org.apache.log4j.plugins.Receiver; -import org.apache.log4j.rule.ExpressionRule; -import org.apache.log4j.rule.Rule; -import org.apache.log4j.spi.Decoder; -import org.apache.log4j.spi.LoggingEvent; - -/** -LogFileXMLReceiver will read an xml-formated log file and make the events in the log -file available to the log4j framework. - -

    This receiver supports log files created using log4j's XMLLayout, as well as -java.util.logging XMLFormatter (via the org.apache.log4j.spi.Decoder interface). - -

    By default, log4j's XMLLayout is supported (no need to specify a decoder in that case). - -

    To configure this receiver to support java.util.logging's XMLFormatter, specify a -'decoder' param of org.apache.log4j.xml.UtilLoggingXMLDecoder. - -

    Tailing -may- work, but not in all cases (try using a file:// URL). If a process has a log file open, -the receiver may be able to read and tail the file. If the process closes the file and reopens the file, -the receiver may not be able to continue tailing the file. - -

    An expressionFilter may be specified. Only events passing the expression will be forwarded to the log4j framework. - -

    Once the event has been "posted", it will be handled by the -appenders currently configured in the LoggerRespository. - -@author Scott Deboy - - @since 1.3 -*/ - -public class LogFileXMLReceiver extends Receiver { - private String fileURL; - private Rule expressionRule; - private String filterExpression; - private String decoder = "org.apache.log4j.xml.XMLDecoder"; - private boolean tailing = false; - - private Decoder decoderInstance; - private Reader reader; - private static final String FILE_KEY = "file"; - private String host; - private String path; - - /** - * Accessor - * - * @return file URL - */ - public String getFileURL() { - return fileURL; - } - - /** - * Specify the URL of the XML-formatted file to process. - * - * @param fileURL - */ - public void setFileURL(String fileURL) { - this.fileURL = fileURL; - } - - /** - * Accessor - * - * @return - */ - public String getDecoder() { - return decoder; - } - - /** - * Specify the class name implementing org.apache.log4j.spi.Decoder that - * can process the file. - * - * @param _decoder - */ - public void setDecoder(String _decoder) { - decoder = _decoder; - } - - /** - * Accessor - * - * @return filter expression - */ - public String getFilterExpression() { - return filterExpression; - } - - /** - * Accessor - * - * @return tailing flag - */ - public boolean isTailing() { - return tailing; - } - - /** - * Set the 'tailing' flag - may only work on file:// URLs and may stop tailing if the - * writing process closes the file and reopens. - * - * @param tailing - */ - public void setTailing(boolean tailing) { - this.tailing = tailing; - } - /** - * Set the filter expression that will cause only events which pass the filter - * to be forwarded to the log4j framework. - * - * @param filterExpression - */ - public void setFilterExpression(String filterExpression) { - this.filterExpression = filterExpression; - } - - private boolean passesExpression(LoggingEvent event) { - if (event != null) { - if (expressionRule != null) { - return (expressionRule.evaluate(event)); - } - } - return true; - } - - public static void main(String[] args) { - /* - LogFileXMLReceiver test = new LogFileXMLReceiver(); - test.setFileURL("file:///c:/samplelog.xml"); - test.setFilterExpression("level >= TRACE"); - test.activateOptions(); - */ - } - - /** - * Close the receiver, release any resources that are accessing the file. - */ - public void shutdown() { - try { - if (reader != null) { - reader.close(); - reader = null; - } - } catch (IOException ioe) { - ioe.printStackTrace(); - } - } - - /** - * Process the file - */ - public void activateOptions() { - new Thread(new Runnable() { - public void run() { - try { - URL url = new URL(fileURL); - host = url.getHost(); - if (host != null && host.equals("")) { - host = FILE_KEY; - } - path = url.getPath(); - } catch (MalformedURLException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - - try { - if (filterExpression != null) { - expressionRule = ExpressionRule - .getRule(filterExpression); - } - } catch (Exception e) { - getLogger() - .warn( - "Invalid filter expression: " - + filterExpression, e); - } - - Class c; - try { - c = Class.forName(decoder); - Object o = c.newInstance(); - if (o instanceof Decoder) { - decoderInstance = (Decoder) o; - } - } catch (ClassNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (InstantiationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - try { - reader = new InputStreamReader(new URL(getFileURL()) - .openStream()); - process(reader); - } catch (FileNotFoundException fnfe) { - getLogger().info("file not available"); - } catch (IOException ioe) { - getLogger().warn("unable to load file", ioe); - return; - } - } - }).start(); - } - - private void process(Reader unbufferedReader) throws IOException { - BufferedReader bufferedReader = new BufferedReader(unbufferedReader); - char[] content = new char[10000]; - getLogger().debug("processing starting: " + fileURL); - int length = 0; - do { - System.out.println("in do loop-about to process"); - while ((length = bufferedReader.read(content)) > -1) { - processEvents(decoderInstance.decodeEvents(String.valueOf(content, - 0, length))); - } - if (tailing) { - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - while (tailing); - getLogger().debug("processing complete: " + fileURL); - - shutdown(); - } - - private void processEvents(Collection c) { - if (c == null) { - return; - } - - for (Iterator iter = c.iterator(); iter.hasNext();) { - LoggingEvent evt = (LoggingEvent) iter.next(); - if (passesExpression(evt)) { - if (evt.getProperty(Constants.HOSTNAME_KEY) != null) { - evt.setProperty(Constants.HOSTNAME_KEY, host); - } - if (evt.getProperty(Constants.APPLICATION_KEY) != null) { - evt.setProperty(Constants.APPLICATION_KEY, path); - } - doPost(evt); - } - } - } -} \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/xml/LogFileXMLReceiverBeanInfo.java b/src/main/java/org/apache/log4j/xml/LogFileXMLReceiverBeanInfo.java deleted file mode 100644 index d350bb317c..0000000000 --- a/src/main/java/org/apache/log4j/xml/LogFileXMLReceiverBeanInfo.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.xml; - -import java.beans.PropertyDescriptor; -import java.beans.SimpleBeanInfo; - - -/** - * BeanInfo class for the meta-data of the LogFileXMLReceiver. - * - */ -public class LogFileXMLReceiverBeanInfo extends SimpleBeanInfo { - /* (non-Javadoc) - * @see java.beans.BeanInfo#getPropertyDescriptors() - */ - public PropertyDescriptor[] getPropertyDescriptors() { - try { - return new PropertyDescriptor[] { - new PropertyDescriptor("fileURL", LogFileXMLReceiver.class), - new PropertyDescriptor("decoder", LogFileXMLReceiver.class), - new PropertyDescriptor("name", LogFileXMLReceiver.class), - new PropertyDescriptor("tailing", LogFileXMLReceiver.class), - new PropertyDescriptor( - "filterExpression", LogFileXMLReceiver.class), - }; - } catch (Exception e) { - } - - return null; - } -} diff --git a/src/main/java/org/apache/log4j/xml/PluginConfigurator.java b/src/main/java/org/apache/log4j/xml/PluginConfigurator.java deleted file mode 100644 index a9b77c3f2a..0000000000 --- a/src/main/java/org/apache/log4j/xml/PluginConfigurator.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.xml; - -/** - * This class is an alias for org.apache.log4j.xml.DOMConfigurator - * provided so Chainsaw can compile against both log4j 1.2 - * and log4j 1.3. In log4j 1.2, configuration of plugins - * requires extending DOMConfigurator. - */ -public final class PluginConfigurator extends - org.apache.log4j.xml.DOMConfigurator { - -} diff --git a/src/main/java/org/apache/log4j/xml/SAXErrorHandler.java b/src/main/java/org/apache/log4j/xml/SAXErrorHandler.java index 56d3eaa88c..43e851bb6c 100644 --- a/src/main/java/org/apache/log4j/xml/SAXErrorHandler.java +++ b/src/main/java/org/apache/log4j/xml/SAXErrorHandler.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,31 +17,30 @@ package org.apache.log4j.xml; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXParseException; - +import org.apache.log4j.helpers.LogLog; public class SAXErrorHandler implements ErrorHandler { - Logger logger = LogManager.getLogger(SAXErrorHandler.class); + + public + void error(final SAXParseException ex) { + emitMessage("Continuable parsing error ", ex); + } - public void error(SAXParseException ex) { - logger.error( - "Parsing error on line " + ex.getLineNumber() + " and column " - + ex.getColumnNumber()); - logger.error(ex.getMessage(), ex.getException()); - //LogLog.error("pid="+ex.getPublicId()+" sid="+ex.getSystemId()); + public + void fatalError(final SAXParseException ex) { + emitMessage("Fatal parsing error ", ex); } - - public void fatalError(SAXParseException ex) { - error(ex); + + public + void warning(final SAXParseException ex) { + emitMessage("Parsing warning ", ex); } - - public void warning(SAXParseException ex) { - logger.warn( - "Parsing error on line " + ex.getLineNumber() + " and column " - + ex.getColumnNumber()); - logger.warn(ex.getMessage(), ex.getException()); + + private static void emitMessage(final String msg, final SAXParseException ex) { + LogLog.warn(msg +ex.getLineNumber()+" and column " + +ex.getColumnNumber()); + LogLog.warn(ex.getMessage(), ex.getException()); } } diff --git a/src/main/java/org/apache/log4j/xml/UnrecognizedElementHandler.java b/src/main/java/org/apache/log4j/xml/UnrecognizedElementHandler.java new file mode 100644 index 0000000000..463d5d989d --- /dev/null +++ b/src/main/java/org/apache/log4j/xml/UnrecognizedElementHandler.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.xml; + +import org.w3c.dom.Element; +import java.util.Properties; + +/** + * When implemented by an object configured by DOMConfigurator, + * the handle method will be called when an unrecognized child + * element is encountered. Unrecognized child elements of + * the log4j:configuration element will be dispatched to + * the logger repository if it supports this interface. + * + * @since 1.2.15 + */ +public interface UnrecognizedElementHandler { + /** + * Called to inform a configured object when + * an unrecognized child element is encountered. + * @param element element, may not be null. + * @param props properties in force, may be null. + * @return true if configured object recognized the element + * @throws Exception throw an exception to prevent activation + * of the configured object. + */ + boolean parseUnrecognizedElement(Element element, Properties props) throws Exception; +} \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/xml/UtilLoggingEntityResolver.java b/src/main/java/org/apache/log4j/xml/UtilLoggingEntityResolver.java deleted file mode 100644 index 5b2ee4a5d6..0000000000 --- a/src/main/java/org/apache/log4j/xml/UtilLoggingEntityResolver.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.xml; - -import org.apache.log4j.LogManager; -import org.xml.sax.EntityResolver; -import org.xml.sax.InputSource; - -import java.io.InputStream; - - -/** - * An {@link EntityResolver} specifically designed to return - * java 1.4's logging dtd, logger.dtd - * which is embedded within the log4j jar file. Based on EntityResolver. - * - * @since 1.3 - * - * @author Paul Austin - * @author Scott Deboy (sdeboy@apache.org) - */ -public final class UtilLoggingEntityResolver implements EntityResolver { - - /** - * Create new instance. - */ - public UtilLoggingEntityResolver() { - super(); - } - - - /** {@inheritDoc} */ - public InputSource resolveEntity(final String publicId, - final String systemId) { - if (systemId.endsWith("logger.dtd")) { - Class clazz = getClass(); - InputStream in = - clazz.getResourceAsStream("/org/apache/log4j/xml/logger.dtd"); - if (in == null) { - LogManager.getLogger(UtilLoggingEntityResolver.class).error( - "Could not find [logger.dtd]. Used [" + clazz.getClassLoader() - + "] class loader in the search."); - return null; - } else { - return new InputSource(in); - } - } else { - return null; - } - } -} diff --git a/src/main/java/org/apache/log4j/xml/UtilLoggingXMLDecoder.java b/src/main/java/org/apache/log4j/xml/UtilLoggingXMLDecoder.java deleted file mode 100644 index 87e9db9c9a..0000000000 --- a/src/main/java/org/apache/log4j/xml/UtilLoggingXMLDecoder.java +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.xml; - -import java.awt.Component; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.LineNumberReader; -import java.io.StringReader; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Map; -import java.util.Vector; - -import javax.swing.ProgressMonitorInputStream; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.apache.log4j.helpers.UtilLoggingLevel; -import org.apache.log4j.spi.Decoder; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.ThrowableInformation; -import org.apache.log4j.spi.LocationInfo; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; - - -/** - * Decodes JDK 1.4's java.util.logging package events - * delivered via XML (using the logger.dtd). - * - * @author Scott Deboy (sdeboy@apache.org) - * @author Paul Smith (psmith@apache.org) - * @since 1.3 - * - */ -public class UtilLoggingXMLDecoder implements Decoder { - //NOTE: xml section is only handed on first delivery of events - //on this first delivery of events, there is no end tag for the log element - /** - * Document prolog. - */ - private static final String BEGIN_PART = - "" - + ""; - /** - * Document close. - */ - private static final String END_PART = ""; - /** - * Document builder. - */ - private DocumentBuilder docBuilder; - /** - * Additional properties. - */ - private Map additionalProperties = new HashMap(); - /** - * Partial event. - */ - private String partialEvent; - /** - * Record end. - */ - private static final String RECORD_END = ""; - /** - * Owner. - */ - private Component owner = null; - - /** - * Create new instance. - * @param o owner - */ - public UtilLoggingXMLDecoder(final Component o) { - this(); - this.owner = o; - } - - /** - * Create new instance. - */ - public UtilLoggingXMLDecoder() { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setValidating(false); - - try { - docBuilder = dbf.newDocumentBuilder(); - docBuilder.setErrorHandler(new SAXErrorHandler()); - docBuilder.setEntityResolver(new UtilLoggingEntityResolver()); - } catch (ParserConfigurationException pce) { - System.err.println("Unable to get document builder"); - } - } - - /** - * Sets an additionalProperty map, where each Key/Value pair is - * automatically added to each LoggingEvent as it is decoded. - * - * This is useful, say, to include the source file name of the Logging events - * @param properties additional properties - */ - public void setAdditionalProperties(final Map properties) { - this.additionalProperties.putAll(properties); - } - - /** - * Converts the LoggingEvent data in XML string format into an actual - * XML Document class instance. - * @param data XML fragment - * @return XML document - */ - private Document parse(final String data) { - if (docBuilder == null || data == null) { - return null; - } - - Document document = null; - - try { - // we change the system ID to a valid URI so that Crimson won't - // complain. Indeed, "log4j.dtd" alone is not a valid URI which - // causes Crimson to barf. The Log4jEntityResolver only cares - // about the "log4j.dtd" ending. - - /** - * resetting the length of the StringBuffer is dangerous, particularly - * on some JDK 1.4 impls, there's a known Bug that causes a memory leak - */ - StringBuffer buf = new StringBuffer(1024); - - if (!data.startsWith(" - // (which willbe processed) and the partial event which - // will be combined and processed in the next section - - //if the document does not contain a record end, - // append it to the partial event string - if (document.lastIndexOf(RECORD_END) == -1) { - partialEvent = partialEvent + document; - return null; - } - - if (document.lastIndexOf(RECORD_END) + RECORD_END.length() - < document.length()) { - newDoc = document.substring(0, - document.lastIndexOf(RECORD_END) + RECORD_END.length()); - newPartialEvent = document.substring( - document.lastIndexOf(RECORD_END) + RECORD_END.length()); - } else { - newDoc = document; - } - if (partialEvent != null) { - newDoc = partialEvent + newDoc; - } - partialEvent = newPartialEvent; - - Document doc = parse(newDoc); - if (doc == null) { - return null; - } - return decodeEvents(doc); - } - return null; - } - - /** - * Converts the string data into an XML Document, and then soaks out the - * relevant bits to form a new LoggingEvent instance which can be used - * by any Log4j element locally. - * @param data XML fragment - * @return a single LoggingEvent or null - */ - public LoggingEvent decode(final String data) { - Document document = parse(data); - - if (document == null) { - return null; - } - - Vector events = decodeEvents(document); - - if (events.size() > 0) { - return (LoggingEvent) events.firstElement(); - } - - return null; - } - - /** - * Given a Document, converts the XML into a Vector of LoggingEvents. - * @param document XML document - * @return vector of logging events - */ - private Vector decodeEvents(final Document document) { - Vector events = new Vector(); - - NodeList eventList = document.getElementsByTagName("record"); - - for (int eventIndex = 0; eventIndex < eventList.getLength(); - eventIndex++) { - Node eventNode = eventList.item(eventIndex); - - Logger logger = null; - long timeStamp = 0L; - Level level = null; - String threadName = null; - Object message = null; - String ndc = null; - String[] exception = null; - String className = null; - String methodName = null; - String fileName = null; - String lineNumber = null; - Hashtable properties = new Hashtable(); - - //format of date: 2003-05-04T11:04:52 - //ignore date or set as a property? using millis in constructor instead - NodeList list = eventNode.getChildNodes(); - int listLength = list.getLength(); - - if (listLength == 0) { - continue; - } - - for (int y = 0; y < listLength; y++) { - String tagName = list.item(y).getNodeName(); - - if (tagName.equalsIgnoreCase("logger")) { - logger = Logger.getLogger(getCData(list.item(y))); - } - - if (tagName.equalsIgnoreCase("millis")) { - timeStamp = Long.parseLong(getCData(list.item(y))); - } - - if (tagName.equalsIgnoreCase("level")) { - level = UtilLoggingLevel.toLevel(getCData(list.item(y))); - } - - if (tagName.equalsIgnoreCase("thread")) { - threadName = getCData(list.item(y)); - } - - if (tagName.equalsIgnoreCase("sequence")) { - properties.put("log4jid", getCData(list.item(y))); - } - - if (tagName.equalsIgnoreCase("message")) { - message = getCData(list.item(y)); - } - - if (tagName.equalsIgnoreCase("class")) { - className = getCData(list.item(y)); - } - - if (tagName.equalsIgnoreCase("method")) { - methodName = getCData(list.item(y)); - } - - if (tagName.equalsIgnoreCase("exception")) { - ArrayList exceptionList = new ArrayList(); - NodeList exList = list.item(y).getChildNodes(); - int exlistLength = exList.getLength(); - - for (int i2 = 0; i2 < exlistLength; i2++) { - Node exNode = exList.item(i2); - String exName = exList.item(i2).getNodeName(); - - if (exName.equalsIgnoreCase("message")) { - exceptionList.add(getCData(exList.item(i2))); - } - - if (exName.equalsIgnoreCase("frame")) { - NodeList exList2 = exNode.getChildNodes(); - int exlist2Length = exList2.getLength(); - - for (int i3 = 0; i3 < exlist2Length; i3++) { - exceptionList.add(getCData(exList2.item(i3)) + "\n"); - } - } - } - - exception = - (String[]) exceptionList.toArray(new String[exceptionList.size()]); - } - } - - /** - * We add all the additional properties to the properties - * hashtable - */ - if (additionalProperties.size() > 0) { - if (properties == null) { - properties = new Hashtable(additionalProperties); - } else { - Iterator i = additionalProperties.entrySet().iterator(); - while (i.hasNext()) { - Map.Entry e = (Map.Entry) i.next(); - if (!(properties.containsKey(e.getKey()))) { - properties.put(e.getKey(), e.getValue()); - } - } - } - } - - LocationInfo info = null; - if ((fileName != null) - || (className != null) - || (methodName != null) - || (lineNumber != null)) { - info = new LocationInfo(fileName, className, methodName, lineNumber); - } else { - info = LocationInfo.NA_LOCATION_INFO; - } - - if (exception == null) { - exception = new String[]{""}; - } - - LoggingEvent loggingEvent = new LoggingEvent(); - loggingEvent.setLogger(logger); - loggingEvent.setTimeStamp(timeStamp); - loggingEvent.setLevel(level); - loggingEvent.setThreadName(threadName); - loggingEvent.setMessage(message); - loggingEvent.setNDC(ndc); - loggingEvent.setThrowableInformation(new ThrowableInformation(exception)); - loggingEvent.setLocationInformation(info); - loggingEvent.setProperties(properties); - - events.add(loggingEvent); - - } - return events; - } - - /** - * Get contents of CDATASection. - * @param n CDATASection - * @return text content of all text or CDATA children of node. - */ - private String getCData(final Node n) { - StringBuffer buf = new StringBuffer(); - NodeList nl = n.getChildNodes(); - - for (int x = 0; x < nl.getLength(); x++) { - Node innerNode = nl.item(x); - - if ( - (innerNode.getNodeType() == Node.TEXT_NODE) - || (innerNode.getNodeType() == Node.CDATA_SECTION_NODE)) { - buf.append(innerNode.getNodeValue()); - } - } - - return buf.toString(); - } -} diff --git a/src/main/java/org/apache/log4j/xml/XMLDecoder.java b/src/main/java/org/apache/log4j/xml/XMLDecoder.java deleted file mode 100644 index 5836932f38..0000000000 --- a/src/main/java/org/apache/log4j/xml/XMLDecoder.java +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.xml; - -import java.awt.Component; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.LineNumberReader; -import java.io.StringReader; -import java.net.URL; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Map; -import java.util.Vector; - -import javax.swing.ProgressMonitorInputStream; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.apache.log4j.spi.Decoder; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.ThrowableInformation; -import org.apache.log4j.spi.LocationInfo; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; - - -/** - * Decodes Logging Events in XML formated into elements that are used by - * Chainsaw. - * - * This decoder can process a collection of log4j:event nodes ONLY - * (no XML declaration nor eventSet node) - * - * NOTE: Only a single LoggingEvent is returned from the decode method - * even though the DTD supports multiple events nested in an eventSet. - * - * @since 1.3 - * - * @author Scott Deboy (sdeboy@apache.org) - * @author Paul Smith (psmith@apache.org) - * - */ -public class XMLDecoder implements Decoder { - /** - * Document prolog. - */ - private static final String BEGINPART = - "" - + "" - + ""; - /** - * Document close. - */ - private static final String ENDPART = ""; - /** - * Record end. - */ - private static final String RECORD_END = ""; - - /** - * Document builder. - */ - private DocumentBuilder docBuilder; - /** - * Additional properties. - */ - private Map additionalProperties = new HashMap(); - /** - * Partial event. - */ - private String partialEvent; - /** - * Owner. - */ - private Component owner = null; - - /** - * Create new instance. - * @param o owner - */ - public XMLDecoder(final Component o) { - this(); - this.owner = o; - } - - /** - * Create new instance. - */ - public XMLDecoder() { - super(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setValidating(false); - - try { - docBuilder = dbf.newDocumentBuilder(); - docBuilder.setErrorHandler(new SAXErrorHandler()); - docBuilder.setEntityResolver(new Log4jEntityResolver()); - } catch (ParserConfigurationException pce) { - System.err.println("Unable to get document builder"); - } - } - - /** - * Sets an additionalProperty map, where each Key/Value pair is - * automatically added to each LoggingEvent as it is decoded. - * - * This is useful, say, to include the source file name of the Logging events - * @param properties additional properties - */ - public void setAdditionalProperties(final Map properties) { - this.additionalProperties = properties; - } - - /** - * Converts the LoggingEvent data in XML string format into an actual - * XML Document class instance. - * @param data XML fragment - * @return dom document - */ - private Document parse(final String data) { - if (docBuilder == null || data == null) { - return null; - } - Document document = null; - - try { - // we change the system ID to a valid URI so that Crimson won't - // complain. Indeed, "log4j.dtd" alone is not a valid URI which - // causes Crimson to barf. The Log4jEntityResolver only cares - // about the "log4j.dtd" ending. - // buf.setLength(0); - - /** - * resetting the length of the StringBuffer is dangerous, particularly - * on some JDK 1.4 impls, there's a known Bug that causes a memory leak - */ - StringBuffer buf = new StringBuffer(1024); - - buf.append(BEGINPART); - buf.append(data); - buf.append(ENDPART); - - InputSource inputSource = - new InputSource(new StringReader(buf.toString())); - inputSource.setSystemId("dummy://log4j.dtd"); - document = docBuilder.parse(inputSource); - } catch (Exception e) { - e.printStackTrace(); - } - - return document; - } - - /** - * Decodes a File into a Vector of LoggingEvents. - * @param url the url of a file containing events to decode - * @return Vector of LoggingEvents - * @throws IOException if IO error during processing. - */ - public Vector decode(final URL url) throws IOException { - LineNumberReader reader; - if (owner != null) { - reader = new LineNumberReader(new InputStreamReader( - new ProgressMonitorInputStream(owner, - "Loading " + url , url.openStream()))); - } else { - reader = new LineNumberReader(new InputStreamReader(url.openStream())); - } - - Vector v = new Vector(); - - String line; - Vector events; - try { - while ((line = reader.readLine()) != null) { - StringBuffer buffer = new StringBuffer(line); - for (int i = 0; i < 1000; i++) { - buffer.append(reader.readLine()).append("\n"); - } - events = decodeEvents(buffer.toString()); - if (events != null) { - v.addAll(events); - } - } - } finally { - partialEvent = null; - try { - if (reader != null) { - reader.close(); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - return v; - } - - /** - * Decodes a String representing a number of events into a - * Vector of LoggingEvents. - * @param document to decode events from - * @return Vector of LoggingEvents - */ - public Vector decodeEvents(final String document) { - if (document != null) { - if (document.trim().equals("")) { - return null; - } - String newDoc = null; - String newPartialEvent = null; - //separate the string into the last portion ending with - // (which will be processed) and the - // partial event which will be combined and - // processed in the next section - - //if the document does not contain a record end, - // append it to the partial event string - if (document.lastIndexOf(RECORD_END) == -1) { - partialEvent = partialEvent + document; - return null; - } - - if (document.lastIndexOf(RECORD_END) - + RECORD_END.length() < document.length()) { - newDoc = document.substring(0, - document.lastIndexOf(RECORD_END) + RECORD_END.length()); - newPartialEvent = document.substring( - document.lastIndexOf(RECORD_END) + RECORD_END.length()); - } else { - newDoc = document; - } - if (partialEvent != null) { - newDoc = partialEvent + newDoc; - } - partialEvent = newPartialEvent; - Document doc = parse(newDoc); - if (doc == null) { - return null; - } - return decodeEvents(doc); - } - return null; - } - - /** - * Converts the string data into an XML Document, and then soaks out the - * relevant bits to form a new LoggingEvent instance which can be used - * by any Log4j element locally. - * @param data XML fragment - * @return a single LoggingEvent - */ - public LoggingEvent decode(final String data) { - Document document = parse(data); - - if (document == null) { - return null; - } - - Vector events = decodeEvents(document); - - if (events.size() > 0) { - return (LoggingEvent) events.firstElement(); - } - - return null; - } - - /** - * Given a Document, converts the XML into a Vector of LoggingEvents. - * @param document XML document - * @return Vector of LoggingEvents - */ - private Vector decodeEvents(final Document document) { - Vector events = new Vector(); - - Logger logger; - long timeStamp; - String level; - String threadName; - Object message = null; - String ndc = null; - String[] exception = null; - String className = null; - String methodName = null; - String fileName = null; - String lineNumber = null; - Hashtable properties = null; - - NodeList nl = document.getElementsByTagName("log4j:eventSet"); - Node eventSet = nl.item(0); - - NodeList eventList = eventSet.getChildNodes(); - - for (int eventIndex = 0; eventIndex < eventList.getLength(); - eventIndex++) { - Node eventNode = eventList.item(eventIndex); - //ignore carriage returns in xml - if (eventNode.getNodeType() != Node.ELEMENT_NODE) { - continue; - } - logger = - Logger.getLogger( - eventNode.getAttributes().getNamedItem("logger").getNodeValue()); - timeStamp = - Long.parseLong( - eventNode.getAttributes().getNamedItem("timestamp").getNodeValue()); - level = eventNode.getAttributes().getNamedItem("level").getNodeValue(); - threadName = - eventNode.getAttributes().getNamedItem("thread").getNodeValue(); - - NodeList list = eventNode.getChildNodes(); - int listLength = list.getLength(); - - for (int y = 0; y < listLength; y++) { - String tagName = list.item(y).getNodeName(); - - if (tagName.equalsIgnoreCase("log4j:message")) { - message = getCData(list.item(y)); - } - - if (tagName.equalsIgnoreCase("log4j:NDC")) { - ndc = getCData(list.item(y)); - } - //still support receiving of MDC and convert to properties - if (tagName.equalsIgnoreCase("log4j:MDC")) { - properties = new Hashtable(); - NodeList propertyList = list.item(y).getChildNodes(); - int propertyLength = propertyList.getLength(); - - for (int i = 0; i < propertyLength; i++) { - String propertyTag = propertyList.item(i).getNodeName(); - - if (propertyTag.equalsIgnoreCase("log4j:data")) { - Node property = propertyList.item(i); - String name = - property.getAttributes().getNamedItem("name").getNodeValue(); - String value = - property.getAttributes().getNamedItem("value").getNodeValue(); - properties.put(name, value); - } - } - } - - if (tagName.equalsIgnoreCase("log4j:throwable")) { - exception = new String[] { - getCData(list.item(y)) - }; - } - - if (tagName.equalsIgnoreCase("log4j:locationinfo")) { - className = - list.item(y).getAttributes().getNamedItem("class").getNodeValue(); - methodName = - list.item(y).getAttributes().getNamedItem("method").getNodeValue(); - fileName = - list.item(y).getAttributes().getNamedItem("file").getNodeValue(); - lineNumber = - list.item(y).getAttributes().getNamedItem("line").getNodeValue(); - } - - if (tagName.equalsIgnoreCase("log4j:properties")) { - if (properties == null) { - properties = new Hashtable(); - } - NodeList propertyList = list.item(y).getChildNodes(); - int propertyLength = propertyList.getLength(); - - for (int i = 0; i < propertyLength; i++) { - String propertyTag = propertyList.item(i).getNodeName(); - - if (propertyTag.equalsIgnoreCase("log4j:data")) { - Node property = propertyList.item(i); - String name = - property.getAttributes().getNamedItem("name").getNodeValue(); - String value = - property.getAttributes().getNamedItem("value").getNodeValue(); - properties.put(name, value); - } - } - } - - /** - * We add all the additional properties to the properties - * hashtable. Don't override properties that already exist - */ - if (additionalProperties.size() > 0) { - if (properties == null) { - properties = new Hashtable(additionalProperties); - } else { - Iterator i = additionalProperties.entrySet().iterator(); - while (i.hasNext()) { - Map.Entry e = (Map.Entry) i.next(); - if (!(properties.containsKey(e.getKey()))) { - properties.put(e.getKey(), e.getValue()); - } - } - } - } - } - Level levelImpl = Level.toLevel(level); - - LocationInfo info; - if ((fileName != null) - || (className != null) - || (methodName != null) - || (lineNumber != null)) { - info = new LocationInfo(fileName, className, methodName, lineNumber); - } else { - info = LocationInfo.NA_LOCATION_INFO; - } - if (exception == null) { - exception = new String[]{""}; - } - - LoggingEvent loggingEvent = new LoggingEvent(); - loggingEvent.setLogger(logger); - loggingEvent.setTimeStamp(timeStamp); - loggingEvent.setLevel(levelImpl); - loggingEvent.setThreadName(threadName); - loggingEvent.setMessage(message); - loggingEvent.setNDC(ndc); - loggingEvent.setThrowableInformation(new ThrowableInformation(exception)); - loggingEvent.setLocationInformation(info); - loggingEvent.setProperties(properties); - - events.add(loggingEvent); - - message = null; - ndc = null; - exception = null; - className = null; - methodName = null; - fileName = null; - lineNumber = null; - properties = null; - } - - return events; - } - - /** - * Get contents of CDATASection. - * @param n CDATASection - * @return text content of all text or CDATA children of node. - */ - private String getCData(final Node n) { - StringBuffer buf = new StringBuffer(); - NodeList nl = n.getChildNodes(); - - for (int x = 0; x < nl.getLength(); x++) { - Node innerNode = nl.item(x); - - if ( - (innerNode.getNodeType() == Node.TEXT_NODE) - || (innerNode.getNodeType() == Node.CDATA_SECTION_NODE)) { - buf.append(innerNode.getNodeValue()); - } - } - - return buf.toString(); - } -} diff --git a/src/main/java/org/apache/log4j/xml/XMLLayout.java b/src/main/java/org/apache/log4j/xml/XMLLayout.java index 494bfd254a..2062a80013 100644 --- a/src/main/java/org/apache/log4j/xml/XMLLayout.java +++ b/src/main/java/org/apache/log4j/xml/XMLLayout.java @@ -15,209 +15,202 @@ * limitations under the License. */ +// Contributors: Mathias Bogaert + package org.apache.log4j.xml; import org.apache.log4j.Layout; import org.apache.log4j.helpers.Transform; -import org.apache.log4j.spi.LoggingEvent; import org.apache.log4j.spi.LocationInfo; +import org.apache.log4j.spi.LoggingEvent; -import java.io.IOException; -import java.io.Writer; -import java.util.Iterator; import java.util.Set; +import java.util.Arrays; /** - * The output of the XMLLayout consists of a series of log4j:event elements as - * defined in the log4j.dtd . It does not - * output a complete well-formed XML file. The output is designed to be included - * as an external entity in a separate file to form a correct XML - * file. - * - *

    - * For example, if abc is the name of the file where the - * XMLLayout ouput goes, then a well-formed XML file would be: - * - *

    - * 
    - *  <?xml version="1.0" ?>
    - * 
    - *  <!DOCTYPE log4j:eventSet SYSTEM "log4j.dtd" [<!ENTITY data SYSTEM "abc">]>
    - * 
    - *  <log4j:eventSet version="1.2" xmlns:log4j="http://jakarta.apache.org/log4j/">
    - *    &data
    - *  </log4j:eventSet>
    - *  
    - * 
    - * - *

    - * This approach enforces the independence of the XMLLayout and the appender - * where it is embedded. - * - *

    - * The version attribute helps components to correctly intrepret - * output generated by XMLLayout. The value of this attribute should be "1.1" - * for output generated by log4j versions prior to log4j 1.2 (final release) and - * "1.2" for relase 1.2 and later. + * The output of the XMLLayout consists of a series of log4j:event + * elements as defined in the log4j.dtd. It does not output a + * complete well-formed XML file. The output is designed to be + * included as an external entity in a separate file to form + * a correct XML file. * - * Contributors: Mathias Bogaert - * - * @author Ceki Gülcü - * @since 0.9.0 - */ + *

    For example, if abc is the name of the file where + * the XMLLayout ouput goes, then a well-formed XML file would be: + * +

    +   <?xml version="1.0" ?>
    + 
    +  <!DOCTYPE log4j:eventSet PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd" [<!ENTITY data SYSTEM "abc">]>
    + 
    +  <log4j:eventSet version="1.2" xmlns:log4j="http://jakarta.apache.org/log4j/">
    + 	  &data;
    +  </log4j:eventSet>
    +  
    + + *

    This approach enforces the independence of the XMLLayout and the + * appender where it is embedded. + * + *

    The version attribute helps components to correctly + * intrepret output generated by XMLLayout. The value of this + * attribute should be "1.1" for output generated by log4j versions + * prior to log4j 1.2 (final release) and "1.2" for relase 1.2 and + * later. + * + * Appenders using this layout should have their encoding + * set to UTF-8 or UTF-16, otherwise events containing + * non ASCII characters could result in corrupted + * log files. + * + * @author Ceki Gülcü + * @since 0.9.0 + * */ public class XMLLayout extends Layout { - private boolean locationInfo = false; - - /** - * Default constructor. - * - * @since 1.3 - */ - public XMLLayout() { - super(); - // The XMLLayout prints and does not ignore exceptions. Hence the - // return value false. - ignoresThrowable = false; - } + private final int DEFAULT_SIZE = 256; + private final int UPPER_LIMIT = 2048; + private StringBuffer buf = new StringBuffer(DEFAULT_SIZE); + private boolean locationInfo = false; + private boolean properties = false; + /** - * The LocationInfo option takes a boolean value. By default, it is - * set to false which means there will be no location information output by - * this layout. If the the option is set to true, then the file name and line - * number of the statement at the origin of the log statement will be output. - * - *

    - * If you are embedding this layout within an {@link + * The LocationInfo option takes a boolean value. By default, + * it is set to false which means there will be no location + * information output by this layout. If the the option is set to + * true, then the file name and line number of the statement at the + * origin of the log statement will be output. + * + *

    If you are embedding this layout within an {@link * org.apache.log4j.net.SMTPAppender} then make sure to set the - * LocationInfo option of that appender as well. - */ + * LocationInfo option of that appender as well. + * */ public void setLocationInfo(boolean flag) { locationInfo = flag; } - + /** - * Returns the current value of the LocationInfo option. + Returns the current value of the LocationInfo option. */ public boolean getLocationInfo() { return locationInfo; } + /** + * Sets whether MDC key-value pairs should be output, default false. + * @param flag new value. + * @since 1.2.15 + */ + public void setProperties(final boolean flag) { + properties = flag; + } + + /** + * Gets whether MDC key-value pairs should be output. + * @return true if MDC key-value pairs are output. + * @since 1.2.15 + */ + public boolean getProperties() { + return properties; + } + /** No options to activate. */ public void activateOptions() { } + /** - * Formats a {@link LoggingEvent}in conformance with the log4j.dtd. - */ - public String format(LoggingEvent event) { - StringBuffer buf = new StringBuffer(); + * Formats a {@link org.apache.log4j.spi.LoggingEvent} in conformance with the log4j.dtd. + * */ + public String format(final LoggingEvent event) { + + // Reset working buffer. If the buffer is too large, then we need a new + // one in order to avoid the penalty of creating a large array. + if(buf.capacity() > UPPER_LIMIT) { + buf = new StringBuffer(DEFAULT_SIZE); + } else { + buf.setLength(0); + } + // We yield to the \r\n heresy. + buf.append("\r\n"); buf.append("\r\n"); - + buf.append("]]>\r\n"); + String ndc = event.getNDC(); - - if (ndc != null) { + if(ndc != null) { buf.append("\r\n"); + Transform.appendEscapingCDATA(buf, ndc); + buf.append("]]>\r\n"); } - - // Set mdcKeySet = event.getMDCKeySet(); - // - // if ((mdcKeySet != null) && (mdcKeySet.size() > 0)) { - // /** - // * Normally a sort isn't required, but for Test Case purposes - // * we need to guarantee a particular order. - // * - // * Besides which, from a human readable point of view, the sorting - // * of the keys is kinda nice.. - // */ - // List sortedList = new ArrayList(mdcKeySet); - // Collections.sort(sortedList); - // - // buf.append("\r\n"); - // - // Iterator iter = sortedList.iterator(); - // - // while (iter.hasNext()) { - // String propName = iter.next().toString(); - // output.write(" \r\n"); - // } - // - // output.write("\r\n"); - // } - - if (!ignoresThrowable) { - String[] s = event.getThrowableStrRep(); - - if (s != null) { - buf.append("\r\n"); + + String[] s = event.getThrowableStrRep(); + if(s != null) { + buf.append("\r\n"); } - - if (locationInfo) { - LocationInfo locationInfo = event.getLocationInformation(); + + if(locationInfo) { + LocationInfo locationInfo = event.getLocationInformation(); buf.append("\r\n"); } - Set propertySet = event.getPropertyKeySet(); - - if ((propertySet != null) && (propertySet.size() > 0)) { - buf.append("\r\n"); - - Iterator propIter = propertySet.iterator(); - - while (propIter.hasNext()) { - String propName = propIter.next().toString(); - buf.append(" \r\n"); - } - - buf.append("\r\n"); + if (properties) { + Set keySet = event.getPropertyKeySet(); + if (keySet.size() > 0) { + buf.append("\r\n"); + Object[] keys = keySet.toArray(); + Arrays.sort(keys); + for (int i = 0; i < keys.length; i++) { + String key = keys[i].toString(); + Object val = event.getMDC(key); + if (val != null) { + buf.append("\r\n"); + } + } + buf.append("\r\n"); + } } - + buf.append("\r\n\r\n"); + return buf.toString(); } + + /** + The XMLLayout prints and does not ignore exceptions. Hence the + return value false. + */ + public boolean ignoresThrowable() { + return false; + } } diff --git a/src/main/java/org/apache/log4j/xml/examples/.cvsignore b/src/main/java/org/apache/log4j/xml/examples/.cvsignore deleted file mode 100644 index f590ca415d..0000000000 --- a/src/main/java/org/apache/log4j/xml/examples/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -doc-files \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/xml/examples/ReportParserError.java b/src/main/java/org/apache/log4j/xml/examples/ReportParserError.java deleted file mode 100644 index 169b4129e2..0000000000 --- a/src/main/java/org/apache/log4j/xml/examples/ReportParserError.java +++ /dev/null @@ -1,33 +0,0 @@ - -package org.apache.log4j.xml.examples; - -/** - - This class is needed for validating a log4j.dtd derived XML file. - - @author Joe Kesselman - - @since 0.8.3 - - */ -public class ReportParserError implements org.xml.sax.ErrorHandler { - - void report(String msg, org.xml.sax.SAXParseException e) { - System.out.println(msg+e.getMessage()+ "\n\tat line="+ e.getLineNumber()+ - " col="+e.getColumnNumber()+ " of "+ - "SystemId=\""+e.getSystemId()+ - "\" PublicID = \""+e.getPublicId()+'\"'); - } - - public void warning(org.xml.sax.SAXParseException e) { - report("WARNING: ", e); - } - - public void error(org.xml.sax.SAXParseException e) { - report("ERROR: ", e); - } - - public void fatalError(org.xml.sax.SAXParseException e) { - report("FATAL: ", e); - } -} diff --git a/src/main/java/org/apache/log4j/xml/examples/XMLSample.java b/src/main/java/org/apache/log4j/xml/examples/XMLSample.java deleted file mode 100644 index 7a79904fcb..0000000000 --- a/src/main/java/org/apache/log4j/xml/examples/XMLSample.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 1999,2004-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.log4j.xml.examples; - -import org.apache.log4j.joran.JoranConfigurator; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; - -/** - * - * This example code shows how to - * read an XML based configuration file using a DOM parser. - * - *

    Sample XML files sample1.xml - * and sample2.xml are provided. - * - *

    Note that the log4j.dtd is not in the local directory. - * It is found by the class loader. - * - * @author Ceki Gülcü - * - */ -public class XMLSample { - - static Logger cat = Logger.getLogger(XMLSample.class.getName()); - - /** - * Command-line entry. - */ - public static void main(String argv[]) { - if(argv.length == 1) { - init(argv[0]); - } else { - Usage("Wrong number of arguments."); - } - - sample(); - } - - /** - * Usage printout. - */ - static void Usage(String msg) { - System.err.println(msg); - System.err.println( "Usage: java " + XMLSample.class.getName() + - "configFile"); - System.exit(1); - } - - /** - * Init the class. - */ - static void init(String configFile) { - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure(configFile, LogManager.getLoggerRepository()); - } - - /** - * Run the sample. - */ - static void sample() { - int i = -1; - - Logger root = Logger.getRootLogger(); - cat.debug("Message " + ++i); - cat.warn ("Message " + ++i); - cat.error("Message " + ++i); - - Exception e = new Exception("Just testing"); - cat.debug("Message " + ++i, e); - } -} diff --git a/src/main/java/org/apache/log4j/xml/examples/extension1.xml b/src/main/java/org/apache/log4j/xml/examples/extension1.xml deleted file mode 100644 index af78d1ea2b..0000000000 --- a/src/main/java/org/apache/log4j/xml/examples/extension1.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/xml/examples/extension2.xml b/src/main/java/org/apache/log4j/xml/examples/extension2.xml deleted file mode 100644 index f0fdd5c88e..0000000000 --- a/src/main/java/org/apache/log4j/xml/examples/extension2.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - -]> - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/xml/examples/package.html b/src/main/java/org/apache/log4j/xml/examples/package.html deleted file mode 100644 index db195a1bb2..0000000000 --- a/src/main/java/org/apache/log4j/xml/examples/package.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - -

    Example usage of log4j with XML (including source code). - -

    This package's shows how log4j can be used with an XML -configuration file. - -

    See source code of XMLSample.java showing how to -configure with an XML file. Sample XML files -sample1.xml, -sample2.xml, -sample3.xml, -sample4.xml, -sample5.xml are provided. - -


    -
    - -Last modified: Wed Apr 12 22:27:25 MDT 2000 - - diff --git a/src/main/java/org/apache/log4j/xml/examples/sample1.xml b/src/main/java/org/apache/log4j/xml/examples/sample1.xml deleted file mode 100644 index 512dfa2032..0000000000 --- a/src/main/java/org/apache/log4j/xml/examples/sample1.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/xml/examples/sample2.xml b/src/main/java/org/apache/log4j/xml/examples/sample2.xml deleted file mode 100644 index 7210e4694a..0000000000 --- a/src/main/java/org/apache/log4j/xml/examples/sample2.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/xml/examples/sample3.xml b/src/main/java/org/apache/log4j/xml/examples/sample3.xml deleted file mode 100644 index 964af8c85b..0000000000 --- a/src/main/java/org/apache/log4j/xml/examples/sample3.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/xml/examples/sample4.xml b/src/main/java/org/apache/log4j/xml/examples/sample4.xml deleted file mode 100644 index 75a21ff61f..0000000000 --- a/src/main/java/org/apache/log4j/xml/examples/sample4.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/xml/examples/sample5.xml b/src/main/java/org/apache/log4j/xml/examples/sample5.xml deleted file mode 100644 index 105bdb5131..0000000000 --- a/src/main/java/org/apache/log4j/xml/examples/sample5.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/xml/log4j.dtd b/src/main/java/org/apache/log4j/xml/log4j.dtd deleted file mode 100644 index 719c20f505..0000000000 --- a/src/main/java/org/apache/log4j/xml/log4j.dtd +++ /dev/null @@ -1,195 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/apache/log4j/xml/logger.dtd b/src/main/java/org/apache/log4j/xml/logger.dtd deleted file mode 100644 index d5f40b78e7..0000000000 --- a/src/main/java/org/apache/log4j/xml/logger.dtd +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/xml/package.html b/src/main/java/org/apache/log4j/xml/package.html index 75378d20f3..8a9ed6e22b 100644 --- a/src/main/java/org/apache/log4j/xml/package.html +++ b/src/main/java/org/apache/log4j/xml/package.html @@ -1,4 +1,21 @@ + diff --git a/src/main/java/org/apache/log4j/xml/test/.cvsignore b/src/main/java/org/apache/log4j/xml/test/.cvsignore deleted file mode 100644 index 31efc8c599..0000000000 --- a/src/main/java/org/apache/log4j/xml/test/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -output* -temp* -current.reg \ No newline at end of file diff --git a/src/main/java/org/apache/log4j/xml/test/DOMTest.java b/src/main/java/org/apache/log4j/xml/test/DOMTest.java deleted file mode 100644 index 4b4cc4064f..0000000000 --- a/src/main/java/org/apache/log4j/xml/test/DOMTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.xml.test; - -import org.apache.log4j.Level; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.joran.JoranConfigurator; - - -//import org.apache.log4j.xml.examples.ReportParserError; -//import org.apache.xerces.parsers.DOMParser; -//import java.io.FileInputStream; -//import org.xml.sax.InputSource; - -/** - * @author Ceki Gülcü - */ -public class DOMTest { - static Logger cat = Logger.getLogger(DOMTest.class); - - public static void main(String[] argv) { - if (argv.length == 1) { - init(argv[0]); - } else { - Usage("Wrong number of arguments."); - } - - test(); - } - - static void Usage(String msg) { - System.err.println(msg); - System.err.println( - "Usage: java " + DOMTest.class.getName() + " configFile"); - System.exit(1); - } - - static void init(String configFile) { - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure(configFile, LogManager.getLoggerRepository()); - } - - static void test() { - int i = -1; - Logger root = Logger.getRootLogger(); - - cat.debug("Message " + ++i); - root.debug("Message " + i); - - cat.info("Message " + ++i); - root.info("Message " + i); - - cat.warn("Message " + ++i); - root.warn("Message " + i); - - cat.error("Message " + ++i); - root.error("Message " + i); - - cat.log(Level.FATAL, "Message " + ++i); - root.log(Level.FATAL, "Message " + i); - - Exception e = new Exception("Just testing"); - cat.debug("Message " + ++i, e); - root.debug("Message " + i, e); - - cat.error("Message " + ++i, e); - root.error("Message " + i, e); - - LogManager.shutdown(); - } -} diff --git a/src/main/java/org/apache/log4j/xml/test/testlog.xml b/src/main/java/org/apache/log4j/xml/test/testlog.xml deleted file mode 100644 index 52aa215291..0000000000 --- a/src/main/java/org/apache/log4j/xml/test/testlog.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/javadoc/org/apache/log4j/xml/doc-files/log4j.dtd b/src/main/javadoc/org/apache/log4j/xml/doc-files/log4j.dtd new file mode 100644 index 0000000000..1aabd96c3b --- /dev/null +++ b/src/main/javadoc/org/apache/log4j/xml/doc-files/log4j.dtd @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/javadoc/org/apache/log4j/xml/examples/XMLSample.java b/src/main/javadoc/org/apache/log4j/xml/examples/XMLSample.java new file mode 100644 index 0000000000..94ef78d198 --- /dev/null +++ b/src/main/javadoc/org/apache/log4j/xml/examples/XMLSample.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.xml.examples; + +import org.apache.log4j.xml.DOMConfigurator; +import org.apache.log4j.Logger; + +/** + + This example code shows how to + read an XML based configuration file using a DOM parser. + +

    Sample XML files sample1.xml + and sample2.xml are provided. + + +

    Note that the log4j.dtd is not in the local directory. + It is found by the class loader. + + @author Ceki Gülcü + +*/ +public class XMLSample { + + static Logger cat = Logger.getLogger(XMLSample.class); + + public + static + void main(String argv[]) { + + if(argv.length == 1) + init(argv[0]); + else + Usage("Wrong number of arguments."); + sample(); + } + + static + void Usage(String msg) { + System.err.println(msg); + System.err.println( "Usage: java " + XMLSample.class.getName() + + "configFile"); + System.exit(1); + } + + static + void init(String configFile) { + DOMConfigurator.configure(configFile); + } + + static + void sample() { + int i = -1; + cat.debug("Message " + ++i); + cat.warn ("Message " + ++i); + cat.error("Message " + ++i); + Exception e = new Exception("Just testing"); + cat.debug("Message " + ++i, e); + } +} diff --git a/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/XMLSample.java b/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/XMLSample.java new file mode 100644 index 0000000000..8ea09f2844 --- /dev/null +++ b/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/XMLSample.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.xml.examples; + +import org.apache.log4j.xml.DOMConfigurator; +import org.apache.log4j.Logger; + +/** + + This example code shows how to + read an XML based configuration file using a DOM parser. + +

    Sample XML files sample1.xml + and sample2.xml are provided. + + +

    Note that the log4j.dtd is not in the local directory. + It is found by the class loader. + + @author Ceki Gülcü + +*/ +public class XMLSample { + + static Logger cat = Logger.getLogger(XMLSample.class); + + public + static + void main(String argv[]) { + + if(argv.length == 1) + init(argv[0]); + else + Usage("Wrong number of arguments."); + sample(); + } + + static + void Usage(String msg) { + System.err.println(msg); + System.err.println( "Usage: java " + XMLSample.class.getName() + + "configFile"); + System.exit(1); + } + + static + void init(String configFile) { + DOMConfigurator.configure(configFile); + } + + static + void sample() { + int i = -1; + cat.debug("Message " + ++i); + cat.warn ("Message " + ++i); + cat.error("Message " + ++i); + Exception e = new Exception("Just testing"); + cat.debug("Message " + ++i, e); + } +} diff --git a/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample1.xml b/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample1.xml new file mode 100644 index 0000000000..bddc001d1e --- /dev/null +++ b/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample1.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample2.xml b/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample2.xml new file mode 100644 index 0000000000..65cdcb13cd --- /dev/null +++ b/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample2.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample3.xml b/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample3.xml new file mode 100644 index 0000000000..cddee2b648 --- /dev/null +++ b/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample3.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample4.xml b/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample4.xml new file mode 100644 index 0000000000..9cef69a8de --- /dev/null +++ b/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample4.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample5.xml b/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample5.xml new file mode 100644 index 0000000000..b1caacf003 --- /dev/null +++ b/src/main/javadoc/org/apache/log4j/xml/examples/doc-files/sample5.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/META-INF/LICENSE b/src/main/resources/META-INF/LICENSE new file mode 100644 index 0000000000..6279e5206d --- /dev/null +++ b/src/main/resources/META-INF/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 1999-2005 The Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/src/main/resources/META-INF/NOTICE b/src/main/resources/META-INF/NOTICE new file mode 100644 index 0000000000..0375732360 --- /dev/null +++ b/src/main/resources/META-INF/NOTICE @@ -0,0 +1,5 @@ +Apache log4j +Copyright 2007 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/src/main/resources/org/apache/log4j/xml/log4j.dtd b/src/main/resources/org/apache/log4j/xml/log4j.dtd new file mode 100644 index 0000000000..f8e433a50e --- /dev/null +++ b/src/main/resources/org/apache/log4j/xml/log4j.dtd @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ntdll/NTEventLogAppender.def b/src/ntdll/NTEventLogAppender.def new file mode 100644 index 0000000000..1cbcee84c8 --- /dev/null +++ b/src/ntdll/NTEventLogAppender.def @@ -0,0 +1,22 @@ +; +; Licensed to the Apache Software Foundation (ASF) under one or more +; contributor license agreements. See the NOTICE file distributed with +; this work for additional information regarding copyright ownership. +; The ASF licenses this file to You under the Apache License, Version 2.0 +; (the "License"); you may not use this file except in compliance with +; the License. You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +; + +LIBRARY "NTEventLogAppender" + +EXPORTS + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE diff --git a/src/ntdll/NTEventLogAppender.rc b/src/ntdll/NTEventLogAppender.rc index f5e2eb1e5f..8808456be1 100755 --- a/src/ntdll/NTEventLogAppender.rc +++ b/src/ntdll/NTEventLogAppender.rc @@ -76,8 +76,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1, 2, 15, 1 - PRODUCTVERSION 1, 2, 15, 1 + FILEVERSION 1, 2, 16, 1 + PRODUCTVERSION 1, 2, 16, 1 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -94,12 +94,13 @@ BEGIN BEGIN VALUE "CompanyName", "Apache Software Foundation" VALUE "FileDescription", "Platform methods for NTEventLogAppender" - VALUE "FileVersion", "1, 2, 15, 1" + VALUE "FileVersion", "1, 2, 16, 1" VALUE "InternalName", "NTEventLogAppender" VALUE "LegalCopyright", "Licensed to the Apache Software Foundation (ASF) under one or more\ncontributor license agreements. See the NOTICE file distributed with\nthis work for additional information regarding copyright ownership.\nThe ASF licenses this file to You under the Apache License, Version 2.0\n(the ""License""); you may not use this file except in compliance with\nthe License. You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an ""AS IS"" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." VALUE "OriginalFilename", "NTEventLogAppender.dll" VALUE "ProductName", "Apache log4j" - VALUE "ProductVersion", "1, 2, 15, 1" + VALUE "ProductVersion", "1, 2, 16, 1" + VALUE "OLESelfRegister", "\0" END END BLOCK "VarFileInfo" diff --git a/src/ntdll/build.xml b/src/ntdll/build.xml index 3a26b86c20..c5f53a6431 100755 --- a/src/ntdll/build.xml +++ b/src/ntdll/build.xml @@ -16,6 +16,18 @@ --> + + @@ -35,7 +47,23 @@ - + + + + + + + + + + + + + + @@ -62,7 +90,7 @@ - -Dclasses.dir=/path/to/log4j/classes must be specified + -Dclasses.dir=/path/to/log4j/classes must be specified @@ -93,7 +121,60 @@ ${jni.win32.include.dir}/jni_md.h not found, NTEventLogAppender.dll build skipped. - + + + + + + + + + + + + + + + + + + + + -Dclasses.dir=/path/to/log4j/classes must be specified + + + + + + + + + + + + + + + + + + + + + + + + rc could not be found or failed, NTEventLogAppender.dll build skipped. + + + + diff --git a/src/ntdll/nteventlog.cpp b/src/ntdll/nteventlog.cpp index e5a9e12fed..2c5c38f897 100644 --- a/src/ntdll/nteventlog.cpp +++ b/src/ntdll/nteventlog.cpp @@ -28,6 +28,67 @@ typedef long long __int64; #include +HINSTANCE gModule = 0; + +class EventSourceMap { +#if _WIN64 + enum { MAX_SOURCES = 256 }; + HANDLE* sources; +public: + EventSourceMap() { + sources = (HANDLE*) calloc(MAX_SOURCES, sizeof(*sources)); + } + + ~EventSourceMap() { + free(sources); + } + + jint createKey(HANDLE handle) { + if (handle != 0) { + // + // find first available null entry (excluding sources[0]) + // + for(int i = 1; i < MAX_SOURCES; i++) { + if (InterlockedCompareExchangePointer(sources + i, handle, 0) == 0) { + return i; + } + } + } + return 0; + } + + HANDLE getHandle(jint key) { + if (key >= 1 && key < MAX_SOURCES) { + return sources[key]; + } + return 0; + } + + HANDLE releaseHandle(jint key) { + if (key >= 1 && key < MAX_SOURCES) { + return InterlockedExchangePointer(sources + key, 0); + } + return 0; + } +#else +public: + EventSourceMap() { + } + + jint createKey(HANDLE handle) { + return (jint) handle; + } + + HANDLE getHandle(jint key) { + return (HANDLE) key; + } + + HANDLE releaseHandle(jint key) { + return (HANDLE) key; + } +#endif +} gEventSources; + /* * Convert log4j Priority to an EventLog category. Each category is * backed by a message resource so that proper category names will @@ -102,7 +163,10 @@ void addRegistryInfo(wchar_t *source) { wcscat(subkey, source); hkey = regGetKey(subkey, &disposition); if (disposition == REG_CREATED_NEW_KEY) { - HMODULE hmodule = GetModuleHandleW(L"NTEventLogAppender.dll"); + HMODULE hmodule = gModule; + if (hmodule == NULL) { + hmodule = GetModuleHandleW(L"NTEventLogAppender.dll"); + } if (hmodule != NULL) { wchar_t modpath[_MAX_PATH]; DWORD modlen = GetModuleFileNameW(hmodule, modpath, _MAX_PATH - 1); @@ -126,7 +190,7 @@ void addRegistryInfo(wchar_t *source) { */ JNIEXPORT jint JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_registerEventSource( JNIEnv *env, jobject java_this, jstring server, jstring source) { - + jchar *nserver = 0; jchar *nsource = 0; @@ -143,7 +207,8 @@ JNIEXPORT jint JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_registerEvent nsource[sourceLen] = 0; } addRegistryInfo((wchar_t*) nsource); - jint handle = (jint)RegisterEventSourceW((const wchar_t*) nserver, (const wchar_t*) nsource); + jint handle = gEventSources.createKey(RegisterEventSourceW( + (const wchar_t*) nserver, (const wchar_t*) nsource)); free(nserver); free(nsource); return handle; @@ -155,12 +220,12 @@ JNIEXPORT jint JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_registerEvent * Signature: (ILjava/lang/String;I)V */ JNIEXPORT void JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_reportEvent( - JNIEnv *env, jobject java_this, jint handle, jstring jstr, jint priority) { - + JNIEnv *env, jobject java_this, jint jhandle, jstring jstr, jint priority) { jboolean localHandle = JNI_FALSE; + HANDLE handle = gEventSources.getHandle(jhandle); if (handle == 0) { // Client didn't give us a handle so make a local one. - handle = (jint)RegisterEventSourceW(NULL, L"Log4j"); + handle = RegisterEventSourceW(NULL, L"Log4j"); localHandle = JNI_TRUE; } @@ -174,14 +239,14 @@ JNIEXPORT void JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_reportEvent( // a message resource which consists of just '%1' which is replaced // by the string we just created. const DWORD messageID = 0x1000; - ReportEventW((HANDLE)handle, getType(priority), + ReportEventW(handle, getType(priority), getCategory(priority), messageID, NULL, 1, 0, (const wchar_t**) &msg, NULL); free((void *)msg); if (localHandle == JNI_TRUE) { // Created the handle here so free it here too. - DeregisterEventSource((HANDLE)handle); + DeregisterEventSource(handle); } return; } @@ -196,7 +261,8 @@ JNIEnv *env, jobject java_this, jint handle) { - DeregisterEventSource((HANDLE)handle); + + DeregisterEventSource(gEventSources.releaseHandle(handle)); } @@ -205,9 +271,13 @@ jint handle) // when invoked using regsvr32 tool. // // -STDAPI __declspec(dllexport) DllRegisterServer(void) { +extern "C" { +__declspec(dllexport) HRESULT __stdcall DllRegisterServer(void) { HRESULT hr = E_FAIL; - HMODULE hmodule = GetModuleHandleW(L"NTEventLogAppender.dll"); + HMODULE hmodule = gModule; + if (hmodule == NULL) { + hmodule = GetModuleHandleW(L"NTEventLogAppender.dll"); + } if (hmodule != NULL) { wchar_t modpath[_MAX_PATH]; DWORD modlen = GetModuleFileNameW(hmodule, modpath, _MAX_PATH - 1); @@ -229,11 +299,11 @@ STDAPI __declspec(dllexport) DllRegisterServer(void) { } if(stat == ERROR_SUCCESS) { DWORD value = 7; - stat == RegSetValueExW(hkey, L"TypesSupported", 0, REG_DWORD, (LPBYTE)&value, sizeof(DWORD)); + stat = RegSetValueExW(hkey, L"TypesSupported", 0, REG_DWORD, (LPBYTE)&value, sizeof(DWORD)); } if(stat == ERROR_SUCCESS) { DWORD value = 6; - stat == RegSetValueExW(hkey, L"CategoryCount", 0, REG_DWORD, (LPBYTE)&value, sizeof(DWORD)); + stat = RegSetValueExW(hkey, L"CategoryCount", 0, REG_DWORD, (LPBYTE)&value, sizeof(DWORD)); } LONG closeStat = RegCloseKey(hkey); if (stat == ERROR_SUCCESS && closeStat == ERROR_SUCCESS) { @@ -251,9 +321,32 @@ STDAPI __declspec(dllexport) DllRegisterServer(void) { // when invoked using regsvr32 tool with /u option. // // -STDAPI __declspec(dllexport) DllUnregisterServer(void) { +__declspec(dllexport) HRESULT __stdcall DllUnregisterServer(void) { LONG stat = RegDeleteKeyW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\Log4j"); return (stat == ERROR_SUCCESS || stat == ERROR_FILE_NOT_FOUND) ? S_OK : E_FAIL; } + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + gModule = hModule; + break; + case DLL_PROCESS_DETACH: + gModule = 0; + break; + + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + break; + } + return TRUE; +} + +} #endif diff --git a/src/performance/java/org/apache/log4j/performance/ListVsVector.java b/src/performance/java/org/apache/log4j/performance/ListVsVector.java new file mode 100644 index 0000000000..7f9c8a4486 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/ListVsVector.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.performance; + + +import java.util.Vector; + +/** + + Compares the performance of looping through a list versus a Vector. + + Chain looping is *20* times faster than vector access on JDK 1.1.7B on NT + +*/ +public class ListVsVector { + + static int RUN_LENGTH = 1000000; + static Vector v = new Vector(); + static Chain head; + static String tmp; + + static + public + void main(String[] args) { + + v.addElement("aaa"); + v.addElement("bbb"); + v.addElement("ccc"); + v.addElement("ddd"); + v.addElement("eee"); + + Chain c = new Chain("aaa"); + head = c; + c.next = new Chain("bbb"); c = c.next; + c.next = new Chain("ccc"); c = c.next; + c.next = new Chain("ddd"); c = c.next; + c.next = new Chain("eee"); + double t; + t = loopChain(); + System.out.println("Looping thourgh the chain took " + t); + + t = loopVector(); + System.out.println("Looping thourgh the vector took " + t); + + } + + static + double loopChain() { + long before = System.currentTimeMillis(); + Chain c; + for(int i = 0; i < RUN_LENGTH; i++) { + c = head; + while(c != null) { + tmp = c.s; + c = c.next; + } + } + return (System.currentTimeMillis() - before)*1000.0/RUN_LENGTH; + } + + static + double loopVector() { + long before = System.currentTimeMillis(); + int size = v.size(); + for(int i = 0; i < RUN_LENGTH; i++) { + for(int j = 0; j < size; j++) + tmp = (String) v.elementAt(j); + } + return (System.currentTimeMillis() - before)*1000.0/RUN_LENGTH; + } + + static class Chain { + public String s; + public Chain next; + + Chain(String s) { + this.s = s; + } + + void setNext(Chain c) { + next = c; + } + } +} diff --git a/tests/src/java/org/apache/log4j/performance/NOPWriter.java b/src/performance/java/org/apache/log4j/performance/NOPWriter.java similarity index 100% rename from tests/src/java/org/apache/log4j/performance/NOPWriter.java rename to src/performance/java/org/apache/log4j/performance/NOPWriter.java diff --git a/tests/src/java/org/apache/log4j/performance/NewVsSetLen.java b/src/performance/java/org/apache/log4j/performance/NewVsSetLen.java similarity index 100% rename from tests/src/java/org/apache/log4j/performance/NewVsSetLen.java rename to src/performance/java/org/apache/log4j/performance/NewVsSetLen.java diff --git a/tests/src/java/org/apache/log4j/performance/NullAppender.java b/src/performance/java/org/apache/log4j/performance/NullAppender.java similarity index 79% rename from tests/src/java/org/apache/log4j/performance/NullAppender.java rename to src/performance/java/org/apache/log4j/performance/NullAppender.java index 044ef8aaa4..32c057ad3b 100644 --- a/tests/src/java/org/apache/log4j/performance/NullAppender.java +++ b/src/performance/java/org/apache/log4j/performance/NullAppender.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,10 +17,9 @@ package org.apache.log4j.performance; -import org.apache.log4j.AppenderSkeleton; import org.apache.log4j.Layout; import org.apache.log4j.spi.LoggingEvent; - +import org.apache.log4j.AppenderSkeleton; /** * A bogus appender which calls the format method of its layout object @@ -32,37 +31,38 @@ * included in the log4j.jar file.

    * */ public class NullAppender extends AppenderSkeleton { + public static String s; public String t; - public NullAppender() { - super(true); - } + public + NullAppender() {} - public NullAppender(Layout layout) { - super(true); + public + NullAppender(Layout layout) { this.layout = layout; } - public void close() { - } + public + void close() {} - public void doAppend(LoggingEvent event) { - if (layout != null) { + public + void doAppend(LoggingEvent event) { + if(layout != null) { t = layout.format(event); s = t; } } - public void append(LoggingEvent event) { + public + void append(LoggingEvent event) { } - /** - * Gets whether appender requires a layout. - * @return false - */ - public boolean requiresLayout() { - return false; + /** + This is a bogus appender but it still uses a layout. + */ + public + boolean requiresLayout() { + return true; } - } diff --git a/tests/src/java/org/apache/log4j/performance/SystemTime.java b/src/performance/java/org/apache/log4j/performance/SystemTime.java similarity index 94% rename from tests/src/java/org/apache/log4j/performance/SystemTime.java rename to src/performance/java/org/apache/log4j/performance/SystemTime.java index 9d83a6d9a3..f5ef4d12b5 100644 --- a/tests/src/java/org/apache/log4j/performance/SystemTime.java +++ b/src/performance/java/org/apache/log4j/performance/SystemTime.java @@ -46,9 +46,8 @@ void main(String[] args) { static double systemCurrentTimeLoop() { long before = System.currentTimeMillis(); - long l; for(int i = 0; i < RUN_LENGTH; i++) { - l = System.currentTimeMillis(); + System.currentTimeMillis(); } return (System.currentTimeMillis() - before)*1000.0/RUN_LENGTH; } @@ -56,9 +55,8 @@ void main(String[] args) { static double currentThreadNameloop() { long before = System.currentTimeMillis(); - String t; for(int i = 0; i < RUN_LENGTH; i++) { - t = Thread.currentThread().getName(); + Thread.currentThread().getName(); } return (System.currentTimeMillis() - before)*1000.0/RUN_LENGTH; } diff --git a/src/performance/java/org/apache/log4j/performance/history/FALKNIS.logging b/src/performance/java/org/apache/log4j/performance/history/FALKNIS.logging new file mode 100644 index 0000000000..6838421fe3 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/history/FALKNIS.logging @@ -0,0 +1,133 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +All tests done with java version "1.2.2" +Classic VM (J2RE 1.2.2 IBM build cadev-19991008 (JIT enabled: jitc)) +-------------- Wed Dec 8 20:55:19 MET 1999 --------------- +Logging to a real file. +Results: 516 525 - average 520 (basic) +Results: 657 655 - average 656 (cgu) + +Logging to a null (nop) output stream. +Results: 63 61 - average 62 (basic) +Results: 155 144 - average 149 (cgu) + +Logging with stack info to a regular file. +Results: 2991 2999 - average 2995 (basic) +Results: 5174 5260 - average 5217 (cgu) + +Logging with stack info to a null (nop) output stream. +Results: 779 780 - average 779 (basic) +Results: 2716 2876 - average 2796 (cgu) + +Result with the DateFormat line in CGULog.java: +static private final java.text.DateFormat __DATETIME_FORMAT = new + java.text.SimpleDateFormat("[HH:mm:ss:SSS z] dd.MM.yy"); +-------------- Wed Dec 8 20:59:25 MET 1999 --------------- +Logging to a real file. +Results: 517 526 - average 521 (basic) +Results: 720 656 - average 688 (cgu) + +Logging to a null (nop) output stream. +Results: 61 63 - average 62 (basic) +Results: 173 171 - average 172 (cgu) + +Logging with stack info to a regular file. +Results: 3034 3048 - average 3041 (basic) +Results: 5125 4603 - average 4864 (cgu) + +Logging with stack info to a null (nop) output stream. +Results: 793 929 - average 861 (basic) +-------------- Mon Jan 3 17:17:53 MET 2000 --------------- +Logging to Writer instead of OutputStrem + +Logging to a real file. +Results: 453 433 432 440 433 436 438 437 437 471 - average 441 (simple) +Results: 611 588 587 619 595 585 596 590 639 600 - average 601 (ttcc) + +Logging to a null (nop) output stream. +Results: 34 29 29 27 29 28 30 27 29 28 - average 29 (simple) +Results: 87 112 89 87 86 87 86 87 86 86 - average 89 (ttcc) + +Logging with stack info to a regular file. +Results: 1806 1786 1808 1807 1816 1862 1818 1808 1825 - average 1816 (simple) +Results: 2391 2196 2170 2229 2206 2191 2183 2181 2244 - average 2221 (ttcc) + +Logging with stack info to a null (nop) output stream. +Results: 763 767 806 772 769 758 756 756 768 - average 768 (simple) +Results: 1046 1067 1095 1042 1037 1034 1058 1082 1057 - average 1058 (ttcc) +-------------- Thu Jan 13 15:08:27 MET 2000 --------------- +Using 0.7.3 style appender.doAppend method + +Logging to a real file. +Results: 436 484 438 443 449 448 440 444 - average 447 (simple) +Results: 665 616 598 596 604 588 603 593 - average 607 (ttcc) + +Logging to a null (nop) output stream. +Results: 24 24 24 23 24 24 27 24 - average 24 (simple) +Results: 81 83 81 81 82 80 80 81 - average 81 (ttcc) + +Logging with stack info to a regular file. +Results: 1434 1392 1578 1430 1413 1409 1410 1409 - average 1434 (simple) +Results: 1769 1801 1886 1783 1790 1754 1763 1771 - average 1789 (ttcc) + +Logging with stack info to a null (nop) output stream. +Results: 726 710 721 695 707 699 707 710 - average 709 (simple) +Results: 961 963 966 933 932 930 932 945 - average 945 (ttcc) +-------------- Fri Jan 21 19:05:34 MET 2000 --------------- +0.7.4 performance, JDK 1.2.2 GA + +Logging to a real file. +Results: 436 432 479 451 457 454 436 434 - average 447 simple +Results: 597 632 585 589 587 593 586 593 - average 595 ttcc/RelTime +Results: 729 745 744 738 782 748 730 765 - average 747 ttcc/AbsTime +Results: 765 832 767 772 763 762 778 770 - average 776 ttcc/Date + +Logging to a NOPWriter. +Results: 17 18 18 17 17 18 18 17 - average 17 simple +Results: 71 80 68 68 68 69 71 68 - average 70 ttcc/RelTime +Results: 165 166 166 168 167 163 164 167 - average 165 ttcc/AbsTime +Results: 176 179 175 178 179 180 175 176 - average 177 ttcc/Date + +Logging with stack info to a regular file. +Results: 1403 1408 1399 1405 1406 1390 1399 1515 - average 1415 simple +Results: 1697 1811 1676 1591 1631 1599 1616 1613 - average 1654 ttcc/RelTime + +Logging with stack info to a NOPWriter. +Results: 599 597 604 595 605 596 597 616 - average 601 simple +Results: 780 764 767 775 765 758 752 765 - average 765 ttcc/RelTime +-------------- Fri Jan 21 19:29:31 MET 2000 --------------- +static Date object + +Logging to a real file. +Results: 467 437 442 442 433 453 438 435 - average 443 simple +Results: 580 583 588 621 586 579 592 585 - average 589 ttcc/RelTime +Results: 737 773 731 734 732 740 762 734 - average 742 ttcc/AbsTime +Results: 755 755 760 805 757 752 770 766 - average 765 ttcc/Date + +Logging to a NOPWriter. +Results: 11 11 12 12 11 11 11 11 - average 11 simple +Results: 51 53 51 52 51 52 51 51 - average 51 ttcc/RelTime +Results: 97 95 95 95 97 98 98 96 - average 96 ttcc/AbsTime +Results: 113 112 113 113 113 110 114 115 - average 112 ttcc/Date + +Logging with stack info to a regular file. +Results: 1391 1426 1410 1403 1454 1471 1475 1470 - average 1437 simple +Results: 1620 1627 1631 1615 1601 1606 1598 1802 - average 1637 ttcc/RelTime + +Logging with stack info to a NOPWriter. +Results: 598 629 609 605 595 602 599 608 - average 605 simple +Results: 759 765 743 757 758 747 773 756 - average 757 ttcc/RelTime diff --git a/src/performance/java/org/apache/log4j/performance/history/GIL.logging b/src/performance/java/org/apache/log4j/performance/history/GIL.logging new file mode 100644 index 0000000000..e282a5f027 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/history/GIL.logging @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +GIL is a AMD Duron running at 800 MHz running W2000 and Sun's JDK 1.3. + +NullAppender: + + 4 SimpleLayout + 4 PatternLayout "%p - %m%n" + 4 PatternLayout "%-5p - %m%n" + 10 TTCCLayout/RELATIVE + 10 PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" + 10 PatternLayout "%r [%t] %-5p %.10c %x - %m%n" + 10 PatternLayout "%r [%t] %-5p %.20c %x - %m%n" + 9 PatternLayout "%r [%t] %-5p %c - %m%n" + 25 TTCCLayout/ISO8601 + 28 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" + 58 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" + 1309 PatternLayout "%l - %m%n" + 1379 PatternLayout "%C.%M.%L - %m%n" + +FileAppender: + + 26 SimpleLayout + 28 PatternLayout "%p - %m%n" + 47 TTCC/RELATIVE + 46 PatternLayout "%r [%t] %-5p %c %x - %m%n" + 70 TTCCLayout/ISO8601 + 75 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" + 99 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" + 1524 PatternLayout "%l - %m%n" + +FileAppender: (ImmediateFlush=false) + + 20 SimpleLayout + 21 PatternLayout "%p - %m%n" + 38 TTCC/RELATIVE + 38 PatternLayout "%r [%t] %-5p %c %x - %m%n" + 62 TTCCLayout/ISO8601 + 67 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" + 86 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" + +Notice the small but noticable performance gain when forgoing +immediate flush. diff --git a/src/performance/java/org/apache/log4j/performance/history/NAPOLI.logging b/src/performance/java/org/apache/log4j/performance/history/NAPOLI.logging new file mode 100644 index 0000000000..418c459e68 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/history/NAPOLI.logging @@ -0,0 +1,223 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +All tests are done using Suns's 1.1.7U JDK on NT +-------------- Sometime in 1999 --------------- +Using OutputStream. +Results: - average 79 (simple) +Results: - average 164 (ttcc) + +Logging to a null (nop) output stream. +Results: - average 56 (simple) +Results: - average 131 (ttcc) + +Logging with stack info to a regular file. +Results: - average 1064 (simple) +Results: - average 1355 (ttcc) + +Logging with stack info to a null (nop) output stream. +Results: - average 1002 (simple) +Results: - average 1272 (ttcc) +-------------- Mon Jan 3 17:30:21 2000 --------------- +Using Writer instead of OutputStream. +Results: 111 98 97 101 106 107 117 100 146 116 - average 109 (simple) +Results: 200 175 175 169 206 214 185 172 173 196 - average 186 (ttcc) + +Logging to a null (nop) output stream. +Results: 23 23 25 28 24 23 23 23 23 23 - average 23 (simple) +Results: 67 66 64 65 75 65 66 64 65 64 - average 66 (ttcc) + +Logging with stack info to a regular file. +Results: 981 986 1051 1021 1016 986 976 991 976 1021 - average 1000 (simple) +Results: 1136 1136 1126 1131 1136 1151 1131 1126 1136 1137 - average 1134 + +Logging with stack info to a null (nop) output stream. +Results: 791 786 821 781 776 791 776 776 781 781 - average 786 (simple) +Results: 911 901 901 896 906 943 906 966 901 906 - average 913 (ttcc) +-------------- Thu Jan 13 18:31:46 2000 --------------- +Using v0.7.3 FileAppender.doAppend +Results: 105 95 91 93 92 94 96 96 - average 95 (simple) +Results: 172 200 165 174 182 168 165 165 - average 173 (ttcc) + +Logging to a null (nop) output stream. +Results: 22 22 26 22 22 21 24 22 - average 22 (simple) +Results: 65 64 66 64 64 64 65 65 - average 64 (ttcc) + +Logging with stack info to a regular file. +Results: 831 921 836 841 836 831 831 841 - average 846 (simple) +Results: 1051 981 981 976 981 991 981 1026 - average 996 (ttcc) + +Logging with stack info to a null (nop) output stream. +Results: 726 721 716 721 716 721 716 791 - average 728 (simple) +Results: 841 841 841 841 841 841 841 841 - average 841 (ttcc) +-------------- Fri Jan 14 15:12:11 2000 --------------- +Using v0.7.3 FileAppender.doAppend and the FilterWriter based architecture + +Logging to a real file. +Results: 96 94 96 95 99 96 92 94 - average 95 (simple) +Results: 178 168 167 205 168 174 172 173 - average 175 (ttcc) + +Logging to a null (nop) output stream. +Results: 28 22 21 22 25 21 22 24 - average 23 (simple) +Results: 67 73 65 64 64 64 64 64 - average 65 (ttcc) + +Logging with stack info to a regular file. +Results: 961 831 846 831 841 831 836 866 - average 855 (simple) +Results: 981 976 1001 971 1242 981 1051 981 - average 1023 (ttcc) + +Logging with stack info to a null (nop) output stream. +Results: 726 716 716 716 716 716 741 731 - average 722 (simple) +Results: 846 841 841 841 841 866 841 841 - average 844 (ttcc) + +Note: only stack printing performance is affected. +-------------- Fri Jan 21 20:42:03 2000 --------------- +release 0.7.4 +Logging to a real file. +Results: 90 94 92 90 92 91 88 92 - average 91 simple +Results: 172 161 162 166 165 165 179 164 - average 166 ttcc/RelTime +Results: 206 207 211 212 221 214 225 206 - average 212 ttcc/AbsTime +Results: 228 236 239 234 233 231 229 240 - average 233 ttcc/Date + +Logging to a NOPWriter. +Results: 21 21 20 20 20 20 20 20 - average 20 simple +Results: 60 60 60 60 60 60 60 60 - average 60 ttcc/RelTime +Results: 96 96 96 96 96 96 96 96 - average 96 ttcc/AbsTime +Results: 111 111 112 111 112 108 111 112 - average 111 ttcc/Date + +Logging with stack info to a regular file. +Results: 1091 1106 1092 1096 1096 1086 1106 1091 - average 1095 simple +Results: 1256 1242 1257 1251 1246 1267 1251 1256 - average 1253 ttcc/RelTime + +Logging with stack info to a NOPWriter. +Results: 866 871 856 856 846 851 846 846 - average 854 simple +Results: 996 986 991 986 996 996 991 986 - average 991 ttcc/RelTime + +-------------- Fri Jan 21 20:26:43 2000 --------------- +0.7.4 + static Date +Logging to a real file. +Results: 93 97 92 91 100 91 95 95 - average 94 simple +Results: 170 177 179 195 214 176 188 167 - average 183 ttcc/RelTime +Results: 215 214 218 212 211 215 217 224 - average 215 ttcc/AbsTime +Results: 296 274 234 235 230 237 232 231 - average 246 ttcc/Date + +Logging to a NOPWriter. +Results: 21 21 20 20 22 20 20 20 - average 20 simple +Results: 60 60 60 60 60 60 60 60 - average 60 ttcc/RelTime +Results: 94 93 94 93 93 94 93 93 - average 93 ttcc/AbsTime +Results: 106 105 106 106 106 106 106 105 - average 105 ttcc/Date + +Logging with stack info to a regular file. +Results: 1096 1091 1096 1087 1106 1091 1101 1091 - average 1094 simple +Results: 1211 1216 1212 1217 1211 1221 1216 1217 - average 1215 ttcc/RelTime + +Logging with stack info to a NOPWriter. +Results: 866 866 861 851 846 856 851 856 - average 856 simple +Results: 956 981 966 966 956 961 961 961 - average 963 ttcc/RelTime + +The static date version is faster by at least 3 microsecs. +-------------- Sat Jan 22 16:54:35 2000 --------------- +static Date in DateFormat and static StringBuffer in TTCCLayout +Logging to a real file. +Results: 92 90 92 93 93 91 89 97 - average 92 simple +Results: 159 161 167 160 159 161 164 159 - average 161 ttcc/RelTime +Results: 206 205 205 203 213 207 224 204 - average 208 ttcc/AbsTime +Results: 220 232 229 231 236 228 231 231 - average 229 ttcc/Date + +Logging to a NOPWriter. +Results: 21 21 20 20 20 20 20 20 - average 20 simple +Results: 55 55 55 55 55 55 55 55 - average 55 ttcc/RelTime +Results: 88 88 87 89 88 92 90 87 - average 88 ttcc/AbsTime +Results: 101 102 101 101 102 102 106 106 - average 102 ttcc/Date + +Logging with stack info to a regular file. +Results: 1101 1096 1111 1106 1112 1097 1101 1101 - average 1103 simple +Results: 1217 1212 1221 1271 1227 1217 1226 1216 - average 1225 ttcc/RelTime + +Logging with stack info to a NOPWriter. +Results: 876 866 866 846 856 851 851 851 - average 857 simple +Results: 961 961 961 956 961 961 951 961 - average 959 ttcc/RelTime +------------------------------------------------------- +227 using sockets and byte buffers +-------------- Sat Jan 29 14:34:19 2000 --------------- +Using DateFormat extensions in TTCCLayout. + +Logging to a real file. +Results: 177 170 173 171 185 188 176 176 - average 177 ttcc/RelTime +Results: 206 200 202 203 207 208 201 202 - average 203 ttcc/AbsTime +Results: 234 240 245 236 238 236 246 269 - average 243 ttcc/DateTime + +Logging to a NOPWriter. +Results: 57 57 57 57 - average 57 ttcc/RelTime +Results: 86 84 85 85 - average 85 ttcc/AbsTime +Results: 113 112 112 112 - average 112 ttcc/DateTime + +Logging with stack info to a regular file. +Results: 1111 1116 1116 1157 - average 1125 simple +Results: 1592 1592 1597 1597 - average 1594 ttcc/RelTime + +Logging with stack info to a NOPWriter. +Results: 866 886 876 866 - average 873 simple +Results: 1312 1312 1302 1302 - average 1307 ttcc/RelTime + +A noticable slowdown in RelTime printing, but sull faster than 0.7.4. +-------------- Thu Feb 3 21:04:35 2000 --------------- +Release 0.7.5 +Logging to a real file. +Results: 91 92 95 100 120 91 95 92 - average 97 simple +Results: 178 176 192 183 176 179 174 181 - average 179 ttcc/RelTime +Results: 211 201 203 203 206 220 210 216 - average 208 ttcc/AbsTime +Results: 238 237 245 233 239 237 239 241 - average 238 ttcc/DateTime + +Logging to a NOPWriter. +Results: 21 21 21 20 - average 20 simple +Results: 58 58 58 58 - average 58 ttcc/RelTime +Results: 87 87 86 86 - average 86 ttcc/AbsTime +Results: 114 113 114 114 - average 113 ttcc/DateTime + +Logging with stack info to a regular file. +Results: 1121 1121 1111 1126 - average 1119 simple +Results: 1622 1617 1597 1622 - average 1614 ttcc/RelTime + +Logging with stack info to a NOPWriter. +Results: 886 881 876 866 - average 877 simple +Results: 1317 1317 1316 1317 - average 1316 ttcc/RelTime + +-------------- Tue Mar 21 16:57:01 2000 --------------- +Release 0.8.2 code + +Results: 30 30 31 31 - average 30 NullAppender/SimpleLayout +Results: 32 32 32 32 - average 32 NullAppender/PatternLayout "%p - %m\n" +Results: 31 31 31 31 - average 31 NullAppender/PatternLayout "%-5p - %m\n" +Results: 65 65 65 65 - average 65 NullAppender/TTCCLayout/RELATIVE +Results: 64 65 64 64 - average 64 NullAppender/PatternLayout "%r [%t] %-5p %c %x - %m\n" +Results: 64 64 64 64 - average 64 NullAppender/PatternLayout "%r [%t] %-5p %.10c %x - %m\n" +Results: 64 65 64 64 - average 64 NullAppender/PatternLayout "%r [%t] %-5p %.20c %x - %m\n" +Results: 58 58 60 58 - average 58 NullAppender/PatternLayout "%r [%t] %-5p %c - %m\n" +Results: 122 124 121 122 - average 122 NullAppender/TTCCLayout/ISO8601 +Results: 152 152 152 152 - average 152 NullAppender/PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m\n" +Results: 405 405 404 405 - average 404 NullAppender/PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m\n" +Results: 111 112 113 110 110 111 114 120 - average 112 FileAppender/SimpleLayout +Results: 127 124 125 129 140 121 121 123 - average 126 FileAppender/PatternLayout "%p - %m\n" +Results: 196 195 186 183 186 190 182 189 - average 188 FileAppender/TTCC/RELATIVE +Results: 188 184 186 195 195 214 193 191 - average 193 FileAppender/PatternLayout "%r [%t] %-5p %c %x - %m\n" +Results: 257 265 300 252 - average 268 FileAppender/TTCCLayout/ISO8601 +Results: 289 332 320 338 308 290 288 290 - average 306 FileAppender/PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m\n" +Results: 574 577 580 572 573 577 576 589 - average 577 FileAppender/PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] + %-5p %c %x - %m\n" + +Notice the good performance of PatternLayout compared to dedicated +SimpleLayout and TTCCLayout except when SimpleDateFormat is used. + diff --git a/src/performance/java/org/apache/log4j/performance/history/TORINO.logging b/src/performance/java/org/apache/log4j/performance/history/TORINO.logging new file mode 100644 index 0000000000..67f32b2364 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/history/TORINO.logging @@ -0,0 +1,217 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +-------------- Fri Nov 5 23:52:59 CET 1999 --------------- +Append based logging +Each ttcc log operation took about 342.3 microsec. +Each simple log operation took about 181.9 microsec. +-------------- Sat Nov 6 13:35:44 CET 1999 --------------- +Configuration file: +LogFile=test +FileAppend=false +DefaultPriority=INFO +RelativeTime=true +ecCategoriesFile=logging.cat + +Defined Categories: +A0123456789=INFO + +Results: 173 172 168 172 170 171 178 170 169 171 - average 171 (simple) +Results: 337 332 347 333 335 335 342 333 335 336 - average 336 (ttcc) +Results: 141 147 145 145 143 144 143 139 145 149 - average 144 (simple) +Results: 294 291 292 279 294 292 292 293 292 304 - average 292 (ttcc) + +APPENDING to construct the log message +Second result logs to NOPOutputStream +-------------- Sat Nov 6 18:08:05 CET 1999 --------------- +Without the cost of evaluating - Buffer optimized + +Results: 82 84 85 82 88 83 84 85 83 82 - average 83 (simple) +Results: 271 273 275 259 271 270 272 272 275 273 - average 271 (ttcc) +Results: 54 53 58 70 55 56 55 54 57 55 - average 56 (simple) +Results: 240 236 234 236 233 239 238 236 234 235 - average 236 (ttcc) + +Conclusion cost of evaluation about 20 micros +-------------- Sat Nov 6 13:47:41 CET 1999 --------------- +Results: 100 100 103 100 102 102 100 100 103 100 - average 101 (simple) +Results: 300 298 300 300 310 294 307 299 299 304 - average 301 (ttcc) +Results: 80 79 78 80 78 79 78 79 77 78 - average 78 (simple) +Results: 259 266 263 267 265 264 263 266 265 269 - average 264 (ttcc) + +buffering to construct the log message +Second result logs to NOPOutputStream + +Conclusion buffering saves ~70 microsecs, or about 70% savings. +-------------- Sat Nov 6 18:19:57 CET 1999 --------------- +Removed " [" and " ]" from theadStr + + +Results: 266 273 264 260 268 266 263 264 265 266 - average 265 (ttcc) +Results: 242 242 237 245 242 239 239 245 227 235 - average 239 (ttcc) +-------------- Sat Nov 6 18:27:09 CET 1999 --------------- +Results: 266 273 265 265 266 268 265 267 268 266 - average 266 (ttcc) +Results: 231 221 225 245 234 227 240 225 225 227 - average 230 (ttcc) + +Optimized " [" + thread.getName() + " ]" +-------------- Thu Nov 11 00:55:20 CET 1999 --------------- +Results: 100 84 84 83 85 85 84 84 84 81 - average 85 (simple) +Results: 206 206 204 209 216 204 199 204 212 206 - average 206 (ttcc) +Results: 56 55 56 56 56 55 56 56 56 56 - average 55 (simple) +Results: 179 190 171 184 186 186 185 185 184 170 - average 182 (ttcc) + +Using Category class. +-------------- Fri Nov 12 22:02:16 CET 1999 --------------- +Starting tests, this make take a few seconds.... + +StackInfoThreshold=INFO + +Results: 3890 3815 3842 3777 3845 +-------------- Fri Nov 12 22:07:01 CET 1999 --------------- +StackInfoThreshold=INFO + +Results: 3779 3979 3938 3989 3929 3757 3791 3986 3792 3772 - average 3871 (ttcc) +Results: 3892 3749 3734 3709 3744 3758 3810 3859 3805 3742 - average 3780 (ttcc) + +-------------- Fri Nov 12 22:27:24 CET 1999 --------------- +StackInfoThreshold=INFO + +Results: 3178 3201 3175 3183 3363 3205 3397 3206 3213 3212 - average 3233 (ttcc) +Results: 3204 3232 3105 3183 3127 3236 3221 3124 3138 3182 - average 3175 (ttcc) + +Avoiding try and catch. + +Conclusion the try and catch costs a whopping 600 millis or about 1/5 +of total time. +-------------- Mon Nov 15 22:14:54 CET 1999 --------------- +StackInfoThreshold=INFO + +Results: 1497 1463 1514 1445 1472 1498 1476 1471 1508 1503 - average 1484 (ttcc) +Results: 1403 1483 1494 1399 1453 1463 1444 1430 1436 1406 - average 1441 (ttcc) + +New code based on internal TracerPrintStream class. +-------------- Mon Nov 15 22:53:34 CET 1999 --------------- +Results: 84 86 86 85 90 86 86 86 85 85 - average 85 (simple) +Results: 219 211 203 205 206 202 203 203 215 204 - average 207 (ttcc) +Results: 58 58 66 58 56 60 64 59 58 57 - average 59 (simple) +Results: 174 188 177 170 173 185 171 172 171 175 - average 175 (ttcc) + +Results: 733 742 745 743 766 744 748 754 750 756 - average 748 (bas) +Results: 1462 1481 1475 1515 1462 1479 1517 1497 1479 1555 - average 1492 (ttcc) +Results: 624 628 622 616 618 612 618 605 606 618 - average 616 (bas) +Results: 1353 1371 1374 1338 1374 1318 1360 1336 1329 1342 - average 1349 (ttcc) + +-------------- Mon Dec 13 21:49:49 CET 1999 --------------- +No Layout indirection in Log. NDC in TTCCLog. + +Results: 82 84 86 83 87 87 88 84 84 81 - average 84 (simple) +Results: 225 221 211 221 220 220 221 221 216 211 - average 218 (ttcc) +Results: 60 58 60 54 60 56 55 59 55 56 - average 57 (simple) +Results: 185 183 189 190 190 188 187 189 187 192 - average 188 (ttcc) + +Results: 725 723 737 733 731 738 756 728 755 738 - average 736 (simple) +Results: 1166 1156 1170 1177 1184 1157 1172 1185 1177 1190 - average 1173 (ttcc) +Results: 607 606 604 616 602 583 602 603 603 605 - average 603 (simple) +Results: 1050 1021 1014 1023 1050 1019 1038 1034 1025 1012 - average 1028 (ttcc) + +-------------- Mon Dec 13 23:30:18 CET 1999 --------------- +Layout indirection in Log. NDC in TTCCLayout +Results: 85 87 86 91 89 86 89 87 84 88 - average 87 (simple) +Results: 214 221 214 212 219 213 224 222 210 210 - average 215 (ttcc) +Results: 66 71 70 70 82 70 66 65 64 68 - average 69 (simple) +Results: 192 193 194 182 195 186 184 193 191 199 - average 190 (ttcc) + +Results: 758 761 743 755 750 778 748 758 737 756 - average 754 (simple) +Results: 1139 1169 1112 1129 1161 1146 1121 1145 1140 1134 - average 1139 (ttcc) +Results: 667 684 699 699 717 700 681 693 680 692 - average 691 (simple) +Results: 1115 1119 1103 1127 1106 1116 1100 1121 1096 1131 - average 1113 (ttcc) +-------------- Tue Dec 28 20:35:17 CET 1999 --------------- +v 0.7.1 using Suns JDK 1.2.2 +Results: 54 55 55 54 55 55 56 54 55 55 - average 54 (simple) +Results: 123 123 125 122 128 122 122 123 124 123 - average 123 (ttcc) + +Results: 41 41 42 42 41 41 42 41 56 41 - average 42 (simple) +Results: 102 102 102 102 102 102 102 101 103 102 - average 102 (ttcc) + +Results: 496 494 491 491 503 505 497 491 495 496 - average 495 (simple) +Results: 609 601 613 607 638 606 610 608 610 607 - average 610 (ttcc) + +Results: 449 451 452 476 450 450 444 455 446 447 - average 452 (simple) +Results: 563 548 555 555 556 545 557 551 545 559 - average 553 (ttcc) + +-------------- Tue Dec 28 23:44:36 CET 1999 --------------- +Writer based log4j + +Results: 65 65 65 64 64 65 66 67 65 65 - average 65 (simple) +Results: 122 121 121 121 121 122 122 122 122 121 - average 121 (ttcc) + +Results: 18 18 18 18 18 18 18 18 18 18 - average 18 (simple) +Results: 60 72 59 59 60 60 60 60 60 60 - average 61 (ttcc) + +Results: 521 523 518 524 529 526 533 530 524 528 - average 525 (simple) +Results: 619 629 621 622 626 622 625 624 616 624 - average 622 (ttcc) + +Results: 412 405 400 404 417 402 409 399 416 402 - average 406 (simple) +Results: 496 492 480 488 482 488 487 492 489 488 - average 488 (ttcc) +-------------- Wed Jan 12 00:05:48 CET 2000 --------------- +0.7.2 code +Starting tests, this make take a few seconds.... + +Logging to a real file. +Results: 64 63 65 64 63 63 64 64 - average 63 (simple) +Results: 124 123 122 125 123 126 122 122 - average 123 (ttcc) + +Logging to a null (nop) output stream. +Results: 17 18 17 18 17 18 17 17 - average 17 (simple) +Results: 60 60 59 59 61 60 60 60 - average 59 (ttcc) + +Logging with stack info to a regular file. +Results: 533 526 535 533 533 534 535 528 - average 532 (simple) +Results: 633 630 633 628 639 619 638 630 - average 631 (ttcc) + +Logging with stack info to a null (nop) output stream. +Results: 407 406 413 402 404 412 426 415 - average 410 (simple) +Results: 491 499 494 495 487 504 497 493 - average 495 (ttcc) + +-------------- Sun Jul 9 21:55:09 CEST 2000 --------------- +IBM JDK 1.1.8, log4j 0.8.5 with NDC + +NullAppender: + +12 SimpleLayout +21 PatternLayout "%p - %m\n" +22 PatternLayout "%-5p - %m\n" +39 TTCCLayout/RELATIVE +39 PatternLayout "%r [%t] %-5p %c{2} %x - %m\n" +37 PatternLayout "%r [%t] %-5p %.10c %x - %m\n" +37 PatternLayout "%r [%t] %-5p %.20c %x - %m\n" +32 PatternLayout "%r [%t] %-5p %c - %m\n" +62 TTCCLayout/ISO8601 +69 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m\n" +222 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m\n" +1172 PatternLayout "%l - %m\n" +1313 PatternLayout "%C.%M.%L - %m\n" + +FileAppender: + +44 SimpleLayout +56 PatternLayout "%p - %m\n" +87 TTCC/RELATIVE +95 PatternLayout "%r [%t] %-5p %c %x - %m\n" +126 TTCCLayout/ISO8601 +147 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m\n" +288 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m\n" +447 PatternLayout "%l - %m\n" + diff --git a/tests/src/java/org/apache/log4j/performance/logging b/src/performance/java/org/apache/log4j/performance/logging similarity index 91% rename from tests/src/java/org/apache/log4j/performance/logging rename to src/performance/java/org/apache/log4j/performance/logging index eaf2aa33c9..2eb51bdc3b 100644 --- a/tests/src/java/org/apache/log4j/performance/logging +++ b/src/performance/java/org/apache/log4j/performance/logging @@ -1,375 +1,389 @@ - -# Test the performance of logging - -# Set the variable REMOTE_HOST to the appropriate value for the -# to perform SocketAppender measurements. - - -LCF=logging.lcf -TARGET_FILE=test -DELAY=1000 -PORT=12345 - -# The results are somehow RUN_LENGTH dependent. Keep RUN_LENGTH the -# same to be able to compare results -LONGRUN=100000 -SHORTRUN=5000 - -#LONGRUN=1 -#SHORTRUN=2 - - -declare -i start=$1 - -#D=-Dlog4j.configDebug -# ------------------------------------------------------------- -function multiRun() { - lcf=$1 - loopLength=$2 - msg=$3 - runLength=$4 - - echo -n "Results: " - - declare -i total - declare -i i - i=0 - total=0 - - while [ $i -lt $loopLength ] - do - i=$i+1 - x=$(java $D org.apache.log4j.performance.Logging $lcf $runLength $5) - if [ $x -lt 100 ]; then - echo -n " " - fi - echo -n "$x " - total=$total+$x - done - - while [ $i -lt 8 ] - do - i=$i+1 - echo -n " " - done - - average=$[ $total / $loopLength ] - echo "- average $average $msg" - -} -# ============================================= -# Echo to $LCF -# ============================================= -function lecho { - echo $* >> $LCF -} -# ============================================= - - -echo "--------------" $(date) "---------------" - - -echo echo "Starting performance measures. This make take a few minutes...." - -declare -i TEST - -echo; echo "NullAppender:"; echo - -TEST=1 -if [ $TEST -ge $start ]; then - multiRun xml/logging$TEST.xml 4 "SimpleLayout" $LONGRUN -fi - -TEST=2 -if [ $TEST -ge $start ]; then - format="%p - %m%n" - multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=3 -if [ $TEST -ge $start ]; then - format="%-5p - %m%n" - multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=4 -if [ $TEST -ge $start ]; then - multiRun xml/logging$TEST.xml 4 "TTCCLayout/RELATIVE" $LONGRUN -fi - -TEST=5 -if [ $TEST -ge $start ]; then - format="%r [%t] %-5p %c{2} %x - %m%n" - multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=6 -if [ $TEST -ge $start ]; then - format="%r [%t] %-5p %.10c %x - %m%n" - multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=7 -if [ $TEST -ge $start ]; then - format="%r [%t] %-5p %.20c %x - %m%n" - multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=8 -if [ $TEST -ge $start ]; then - format="%r [%t] %-5p %c - %m%n" - multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=9 -if [ $TEST -ge $start ]; then - multiRun xml/logging$TEST.xml 4 "TTCCLayout/ISO8601" $LONGRUN -fi - -TEST=10 -if [ $TEST -ge $start ]; then - format="%d{ISO8601} [%t] %-5p %c %x - %m%n" - multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=11 -if [ $TEST -ge $start ]; then - format="%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=12 -if [ $TEST -ge $start ]; then - format="%l - %m%n" - multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $SHORTRUN -fi - -TEST=13 -if [ $TEST -ge $start ]; then - format="%C.%M.%L - %m%n" - multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $SHORTRUN -fi - -echo -echo "FileAppender: " -echo - - -TEST=100 -if [ $TEST -ge $start ]; then - multiRun xml/logging$TEST.xml 8 "SimpleLayout" $LONGRUN -fi - -TEST=101 -if [ $TEST -ge $start ]; then - format="%p - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=102 -if [ $TEST -ge $start ]; then - multiRun xml/logging$TEST.xml 8 "TTCC/RELATIVE" $LONGRUN -fi - -TEST=103 -if [ $TEST -ge $start ]; then - format="%r [%t] %-5p %c - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=104 -if [ $TEST -ge $start ]; then - multiRun xml/logging$TEST.xml 8 "TTCCLayout/ISO8601" $LONGRUN -fi - - -TEST=105 -if [ $TEST -ge $start ]; then - format="%d{ISO8601} [%t] %-5p %c %x - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=106 -if [ $TEST -ge $start ]; then - format="%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN -fi - -echo ================== 107 =============================== -TEST=107 -if [ $TEST -ge $start ]; then - format="%l - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $SHORTRUN -fi - -echo ------------------------------------- -echo "FileAppender: ImmediateFlush=false" -echo ------------------------------------- - -TEST=200 -if [ $TEST -ge $start ]; then - multiRun xml/logging$TEST.xml 8 "SimpleLayout" $LONGRUN -fi - -TEST=201 -if [ $TEST -ge $start ]; then - format="%p - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=202 -if [ $TEST -ge $start ]; then - multiRun xml/logging$TEST.xml 8 "TTCC/RELATIVE" $LONGRUN -fi - -TEST=203 -if [ $TEST -ge $start ]; then - format="%r [%t] %-5p %c - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=204 -if [ $TEST -ge $start ]; then - multiRun xml/logging$TEST.xml 8 "TTCCLayout/ISO8601" $LONGRUN -fi - -TEST=205 -if [ $TEST -ge $start ]; then - format="%d{ISO8601} [%t] %-5p %c %x - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=206 -if [ $TEST -ge $start ]; then - format="%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=207 -if [ $TEST -ge $start ]; then - format="%l - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $SHORTRUN -fi - -echo ------------------------------------- -echo "FileAppender: BufferedIO=true" -echo ------------------------------------- - -TEST=220 -if [ $TEST -ge $start ]; then - multiRun xml/logging$TEST.xml 8 "SimpleLayout" $LONGRUN -fi - -TEST=221 -if [ $TEST -ge $start ]; then - format="%p - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=222 -if [ $TEST -ge $start ]; then - multiRun xml/logging$TEST.xml 8 "TTCC/RELATIVE" $LONGRUN -fi - -TEST=223 -if [ $TEST -ge $start ]; then - format="%r [%t] %-5p %c - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=224 -if [ $TEST -ge $start ]; then - multiRun xml/logging$TEST.xml 8 "TTCCLayout/ISO8601" $LONGRUN -fi - -TEST=225 -if [ $TEST -ge $start ]; then - format="%d{ISO8601} [%t] %-5p %c %x - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=226 -if [ $TEST -ge $start ]; then - format="%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=227 -if [ $TEST -ge $start ]; then - format="%l - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $SHORTRUN -fi - - -echo ================================== -echo Async appender -echo ================================== - -TEST=300 -if [ $TEST -ge $start ]; then - multiRun xml/logging$TEST.xml 8 "SimpleLayout" $LONGRUN -fi - -TEST=301 -if [ $TEST -ge $start ]; then - format="%p - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=302 -if [ $TEST -ge $start ]; then - multiRun xml/logging$TEST.xml 8 "TTCCLayout/RELATIVE" $LONGRUN -fi - -TEST=303 -if [ $TEST -ge $start ]; then - format="%r [%t] %-5p %c - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=304 -if [ $TEST -ge $start ]; then - multiRun xml/logging$TEST.xml 8 "TTCCLayout/ISO8601" $LONGRUN -fi - - -TEST=305 -if [ $TEST -ge $start ]; then - format="%d{ISO8601} [%t] %-5p %c %x - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=306 -if [ $TEST -ge $start ]; then - format="%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN -fi - -TEST=307 -if [ $TEST -ge $start ]; then - format="%l - %m%n" - multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $SHORTRUN -fi - - -# =============================================================== -# Remote logging -# =============================================================== -TEST=1000 -#RL=1000 -RL=10000 -if [ $TEST -ge $start ]; then - java org.apache.log4j.performance.Logging xml/logging$TEST.xml $RL 100 100 - #multiRun 4 "SocketAppender" $SHORTRUN $DELAY -fi - - -TEST=1001 -#RL=1000 -RL=30000 -if [ $TEST -ge $start ]; then - java org.apache.log4j.performance.Logging xml/logging$TEST.xml $RL - #multiRun 4 "SocketAppender" $SHORTRUN $DELAY -fi - - +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Test the performance of logging + +# Set the variable REMOTE_HOST to the appropriate value for the +# to perform SocketAppender measurements. + + +LCF=logging.lcf +TARGET_FILE=test +DELAY=1000 +PORT=12345 + +# The results are somehow RUN_LENGTH dependent. Keep RUN_LENGTH the +# same to be able to compare results +LONGRUN=100000 +SHORTRUN=5000 + +#LONGRUN=1 +#SHORTRUN=2 + + +declare -i start=$1 + +#D=-Dlog4j.configDebug +# ------------------------------------------------------------- +function multiRun() { + lcf=$1 + loopLength=$2 + msg=$3 + runLength=$4 + + echo -n "Results: " + + declare -i total + declare -i i + i=0 + total=0 + + while [ $i -lt $loopLength ] + do + i=$i+1 + x=$(java $D org.apache.log4j.performance.Logging $lcf $runLength $5) + if [ $x -lt 100 ]; then + echo -n " " + fi + echo -n "$x " + total=$total+$x + done + + while [ $i -lt 8 ] + do + i=$i+1 + echo -n " " + done + + average=$[ $total / $loopLength ] + echo "- average $average $msg" + +} +# ============================================= +# Echo to $LCF +# ============================================= +function lecho { + echo $* >> $LCF +} +# ============================================= + + +echo "--------------" $(date) "---------------" + + +echo echo "Starting performance measures. This make take a few minutes...." + +declare -i TEST + +echo; echo "NullAppender:"; echo + +TEST=1 +if [ $TEST -ge $start ]; then + multiRun xml/logging$TEST.xml 4 "SimpleLayout" $LONGRUN +fi + +TEST=2 +if [ $TEST -ge $start ]; then + format="%p - %m%n" + multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=3 +if [ $TEST -ge $start ]; then + format="%-5p - %m%n" + multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=4 +if [ $TEST -ge $start ]; then + multiRun xml/logging$TEST.xml 4 "TTCCLayout/RELATIVE" $LONGRUN +fi + +TEST=5 +if [ $TEST -ge $start ]; then + format="%r [%t] %-5p %c{2} %x - %m%n" + multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=6 +if [ $TEST -ge $start ]; then + format="%r [%t] %-5p %.10c %x - %m%n" + multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=7 +if [ $TEST -ge $start ]; then + format="%r [%t] %-5p %.20c %x - %m%n" + multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=8 +if [ $TEST -ge $start ]; then + format="%r [%t] %-5p %c - %m%n" + multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=9 +if [ $TEST -ge $start ]; then + multiRun xml/logging$TEST.xml 4 "TTCCLayout/ISO8601" $LONGRUN +fi + +TEST=10 +if [ $TEST -ge $start ]; then + format="%d{ISO8601} [%t] %-5p %c %x - %m%n" + multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=11 +if [ $TEST -ge $start ]; then + format="%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" + multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=12 +if [ $TEST -ge $start ]; then + format="%l - %m%n" + multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $SHORTRUN +fi + +TEST=13 +if [ $TEST -ge $start ]; then + format="%C.%M.%L - %m%n" + multiRun xml/logging$TEST.xml 4 "PatternLayout \"$format\"" $SHORTRUN +fi + +echo +echo "FileAppender: " +echo + + +TEST=100 +if [ $TEST -ge $start ]; then + multiRun xml/logging$TEST.xml 8 "SimpleLayout" $LONGRUN +fi + +TEST=101 +if [ $TEST -ge $start ]; then + format="%p - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=102 +if [ $TEST -ge $start ]; then + multiRun xml/logging$TEST.xml 8 "TTCC/RELATIVE" $LONGRUN +fi + +TEST=103 +if [ $TEST -ge $start ]; then + format="%r [%t] %-5p %c - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=104 +if [ $TEST -ge $start ]; then + multiRun xml/logging$TEST.xml 8 "TTCCLayout/ISO8601" $LONGRUN +fi + + +TEST=105 +if [ $TEST -ge $start ]; then + format="%d{ISO8601} [%t] %-5p %c %x - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=106 +if [ $TEST -ge $start ]; then + format="%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN +fi + +echo ================== 107 =============================== +TEST=107 +if [ $TEST -ge $start ]; then + format="%l - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $SHORTRUN +fi + +echo ------------------------------------- +echo "FileAppender: ImmediateFlush=false" +echo ------------------------------------- + +TEST=200 +if [ $TEST -ge $start ]; then + multiRun xml/logging$TEST.xml 8 "SimpleLayout" $LONGRUN +fi + +TEST=201 +if [ $TEST -ge $start ]; then + format="%p - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=202 +if [ $TEST -ge $start ]; then + multiRun xml/logging$TEST.xml 8 "TTCC/RELATIVE" $LONGRUN +fi + +TEST=203 +if [ $TEST -ge $start ]; then + format="%r [%t] %-5p %c - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=204 +if [ $TEST -ge $start ]; then + multiRun xml/logging$TEST.xml 8 "TTCCLayout/ISO8601" $LONGRUN +fi + +TEST=205 +if [ $TEST -ge $start ]; then + format="%d{ISO8601} [%t] %-5p %c %x - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=206 +if [ $TEST -ge $start ]; then + format="%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=207 +if [ $TEST -ge $start ]; then + format="%l - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $SHORTRUN +fi + +echo ------------------------------------- +echo "FileAppender: BufferedIO=true" +echo ------------------------------------- + +TEST=220 +if [ $TEST -ge $start ]; then + multiRun xml/logging$TEST.xml 8 "SimpleLayout" $LONGRUN +fi + +TEST=221 +if [ $TEST -ge $start ]; then + format="%p - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=222 +if [ $TEST -ge $start ]; then + multiRun xml/logging$TEST.xml 8 "TTCC/RELATIVE" $LONGRUN +fi + +TEST=223 +if [ $TEST -ge $start ]; then + format="%r [%t] %-5p %c - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=224 +if [ $TEST -ge $start ]; then + multiRun xml/logging$TEST.xml 8 "TTCCLayout/ISO8601" $LONGRUN +fi + +TEST=225 +if [ $TEST -ge $start ]; then + format="%d{ISO8601} [%t] %-5p %c %x - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=226 +if [ $TEST -ge $start ]; then + format="%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=227 +if [ $TEST -ge $start ]; then + format="%l - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $SHORTRUN +fi + + +echo ================================== +echo Async appender +echo ================================== + +TEST=300 +if [ $TEST -ge $start ]; then + multiRun xml/logging$TEST.xml 8 "SimpleLayout" $LONGRUN +fi + +TEST=301 +if [ $TEST -ge $start ]; then + format="%p - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=302 +if [ $TEST -ge $start ]; then + multiRun xml/logging$TEST.xml 8 "TTCCLayout/RELATIVE" $LONGRUN +fi + +TEST=303 +if [ $TEST -ge $start ]; then + format="%r [%t] %-5p %c - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=304 +if [ $TEST -ge $start ]; then + multiRun xml/logging$TEST.xml 8 "TTCCLayout/ISO8601" $LONGRUN +fi + + +TEST=305 +if [ $TEST -ge $start ]; then + format="%d{ISO8601} [%t] %-5p %c %x - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=306 +if [ $TEST -ge $start ]; then + format="%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $LONGRUN +fi + +TEST=307 +if [ $TEST -ge $start ]; then + format="%l - %m%n" + multiRun xml/logging$TEST.xml 8 "PatternLayout \"$format\"" $SHORTRUN +fi + + +# =============================================================== +# Remote logging +# =============================================================== +TEST=1000 +#RL=1000 +RL=10000 +if [ $TEST -ge $start ]; then + java org.apache.log4j.performance.Logging xml/logging$TEST.xml $RL 100 100 + #multiRun 4 "SocketAppender" $SHORTRUN $DELAY +fi + + +TEST=1001 +#RL=1000 +RL=30000 +if [ $TEST -ge $start ]; then + java org.apache.log4j.performance.Logging xml/logging$TEST.xml $RL + #multiRun 4 "SocketAppender" $SHORTRUN $DELAY +fi + + diff --git a/src/performance/java/org/apache/log4j/performance/package.html b/src/performance/java/org/apache/log4j/performance/package.html new file mode 100644 index 0000000000..4e49a94bad --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/package.html @@ -0,0 +1,36 @@ + + + + + + + + +

    Package to measure the performance of the different log4j + components. +

    + +

    The + org.apache.log4j.performance package is intended + for internal use only. Consequently, the classes in this + package are not included in the log4j.jar file. +

    + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging1.xml b/src/performance/java/org/apache/log4j/performance/xml/logging1.xml new file mode 100644 index 0000000000..630c5b9eb4 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging1.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging10.xml b/src/performance/java/org/apache/log4j/performance/xml/logging10.xml new file mode 100644 index 0000000000..1477f8cd98 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging10.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging100.xml b/src/performance/java/org/apache/log4j/performance/xml/logging100.xml new file mode 100644 index 0000000000..42111a3737 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging100.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging1000.xml b/src/performance/java/org/apache/log4j/performance/xml/logging1000.xml new file mode 100644 index 0000000000..349babe8c9 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging1000.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging101.xml b/src/performance/java/org/apache/log4j/performance/xml/logging101.xml new file mode 100644 index 0000000000..fcf49618e7 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging101.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging102.xml b/src/performance/java/org/apache/log4j/performance/xml/logging102.xml new file mode 100644 index 0000000000..7670db1261 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging102.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging103.xml b/src/performance/java/org/apache/log4j/performance/xml/logging103.xml new file mode 100644 index 0000000000..3af8adfc84 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging103.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging104.xml b/src/performance/java/org/apache/log4j/performance/xml/logging104.xml new file mode 100644 index 0000000000..5148ab3722 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging104.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging105.xml b/src/performance/java/org/apache/log4j/performance/xml/logging105.xml new file mode 100644 index 0000000000..b63e49f17b --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging105.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging106.xml b/src/performance/java/org/apache/log4j/performance/xml/logging106.xml new file mode 100644 index 0000000000..9ad3a03b12 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging106.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging107.xml b/src/performance/java/org/apache/log4j/performance/xml/logging107.xml new file mode 100644 index 0000000000..248ab4539d --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging107.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging11.xml b/src/performance/java/org/apache/log4j/performance/xml/logging11.xml new file mode 100644 index 0000000000..d196ac7018 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging11.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging12.xml b/src/performance/java/org/apache/log4j/performance/xml/logging12.xml new file mode 100644 index 0000000000..8997c5fcc8 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging12.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging13.xml b/src/performance/java/org/apache/log4j/performance/xml/logging13.xml new file mode 100644 index 0000000000..3eba7c5a32 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging13.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging2.xml b/src/performance/java/org/apache/log4j/performance/xml/logging2.xml new file mode 100644 index 0000000000..159943d2b2 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging2.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging200.xml b/src/performance/java/org/apache/log4j/performance/xml/logging200.xml new file mode 100644 index 0000000000..690548d6ef --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging200.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging201.xml b/src/performance/java/org/apache/log4j/performance/xml/logging201.xml new file mode 100644 index 0000000000..906511807e --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging201.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging202.xml b/src/performance/java/org/apache/log4j/performance/xml/logging202.xml new file mode 100644 index 0000000000..2190be0496 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging202.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging203.xml b/src/performance/java/org/apache/log4j/performance/xml/logging203.xml new file mode 100644 index 0000000000..ed7d0711e9 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging203.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging204.xml b/src/performance/java/org/apache/log4j/performance/xml/logging204.xml new file mode 100644 index 0000000000..b475c12bbf --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging204.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging205.xml b/src/performance/java/org/apache/log4j/performance/xml/logging205.xml new file mode 100644 index 0000000000..5f896e05e4 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging205.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging206.xml b/src/performance/java/org/apache/log4j/performance/xml/logging206.xml new file mode 100644 index 0000000000..d23dff1653 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging206.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging207.xml b/src/performance/java/org/apache/log4j/performance/xml/logging207.xml new file mode 100644 index 0000000000..87dddafb15 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging207.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging220.xml b/src/performance/java/org/apache/log4j/performance/xml/logging220.xml new file mode 100644 index 0000000000..2024e73d80 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging220.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging221.xml b/src/performance/java/org/apache/log4j/performance/xml/logging221.xml new file mode 100644 index 0000000000..cbaf466542 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging221.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging222.xml b/src/performance/java/org/apache/log4j/performance/xml/logging222.xml new file mode 100644 index 0000000000..3fd2d3733e --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging222.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging223.xml b/src/performance/java/org/apache/log4j/performance/xml/logging223.xml new file mode 100644 index 0000000000..58f867de63 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging223.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging224.xml b/src/performance/java/org/apache/log4j/performance/xml/logging224.xml new file mode 100644 index 0000000000..8886e46473 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging224.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging225.xml b/src/performance/java/org/apache/log4j/performance/xml/logging225.xml new file mode 100644 index 0000000000..78788c509a --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging225.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging226.xml b/src/performance/java/org/apache/log4j/performance/xml/logging226.xml new file mode 100644 index 0000000000..f8fb1fc87e --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging226.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging227.xml b/src/performance/java/org/apache/log4j/performance/xml/logging227.xml new file mode 100644 index 0000000000..b36a157301 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging227.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging3.xml b/src/performance/java/org/apache/log4j/performance/xml/logging3.xml new file mode 100644 index 0000000000..0f2dc4625e --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging3.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging300.xml b/src/performance/java/org/apache/log4j/performance/xml/logging300.xml new file mode 100644 index 0000000000..d833f09ecf --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging300.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging301.xml b/src/performance/java/org/apache/log4j/performance/xml/logging301.xml new file mode 100644 index 0000000000..f9bf7588d8 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging301.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging302.xml b/src/performance/java/org/apache/log4j/performance/xml/logging302.xml new file mode 100644 index 0000000000..0be18382f1 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging302.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging303.xml b/src/performance/java/org/apache/log4j/performance/xml/logging303.xml new file mode 100644 index 0000000000..8a724a2f7e --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging303.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging304.xml b/src/performance/java/org/apache/log4j/performance/xml/logging304.xml new file mode 100644 index 0000000000..472d4571c6 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging304.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging305.xml b/src/performance/java/org/apache/log4j/performance/xml/logging305.xml new file mode 100644 index 0000000000..436803b536 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging305.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging306.xml b/src/performance/java/org/apache/log4j/performance/xml/logging306.xml new file mode 100644 index 0000000000..115ba896a0 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging306.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging307.xml b/src/performance/java/org/apache/log4j/performance/xml/logging307.xml new file mode 100644 index 0000000000..045b99b43a --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging307.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging4.xml b/src/performance/java/org/apache/log4j/performance/xml/logging4.xml new file mode 100644 index 0000000000..ff19b73632 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging4.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging5.xml b/src/performance/java/org/apache/log4j/performance/xml/logging5.xml new file mode 100644 index 0000000000..61065dcc88 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging5.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging6.xml b/src/performance/java/org/apache/log4j/performance/xml/logging6.xml new file mode 100644 index 0000000000..57810a8edf --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging6.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging7.xml b/src/performance/java/org/apache/log4j/performance/xml/logging7.xml new file mode 100644 index 0000000000..2104f2b44b --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging7.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging8.xml b/src/performance/java/org/apache/log4j/performance/xml/logging8.xml new file mode 100644 index 0000000000..8a8c7b28ae --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging8.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/performance/java/org/apache/log4j/performance/xml/logging9.xml b/src/performance/java/org/apache/log4j/performance/xml/logging9.xml new file mode 100644 index 0000000000..26b25609f0 --- /dev/null +++ b/src/performance/java/org/apache/log4j/performance/xml/logging9.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/site/apt/download.apt b/src/site/apt/download.apt index 8748cf3c59..5e41d1e19c 100644 --- a/src/site/apt/download.apt +++ b/src/site/apt/download.apt @@ -13,14 +13,14 @@ ~~ See the License for the specific language governing permissions and ~~ limitations under the License. ------ -Download Apache log4j 1.3 +Download Apache log4j 1.2 ------ ------ ------ -Download Apache log4j 1.3alpha-8 +Download Apache log4j 1.2.17 - Apache log4j 1.3alpha-8 is distributed under the {{{http://www.apache.org/licenses/LICENSE-2.0.html} Apache License, version 2.0}}. + Apache log4j 1.2.17 is distributed under the {{{http://www.apache.org/licenses/LICENSE-2.0.html} Apache License, version 2.0}}. The link in the Mirrors column should display a list of available mirrors with a default selection based on your inferred location. If you do not see that page, @@ -30,13 +30,29 @@ Download Apache log4j 1.3alpha-8 *-------------------------+---------+----------+-----------+ | | Mirrors | Checksum | Signature | *-------------------------+---------+----------+-----------+ -| Apache log4j 1.3alpha-8 (tar.gz) | {{{http://www.apache.org/dyn/closer.cgi/logging/log4j/1.3alpha-8/apache-log4j-1.3alpha-8.tar.gz} apache-log4j-1.3alpha-8.tar.gz}} | {{{http://www.apache.org/dist/logging/log4j/1.3alpha-8/apache-log4j-1.3alpha-8.tar.gz.md5} apache-log4j-1.3alpha-8.tar.gz.md5}} | {{{http://www.apache.org/dist/logging/log4j/1.3alpha-8/apache-log4j-1.3alpha-8.tar.gz.asc} apache-log4j-1.3alpha-8.tar.gz.asc}} | +| Apache log4j 1.2.17 (tar.gz) | {{{http://www.apache.org/dyn/closer.cgi/logging/log4j/1.2.17/log4j-1.2.17.tar.gz} log4j-1.2.17.tar.gz}} | {{{http://www.apache.org/dist/logging/log4j/1.2.17/log4j-1.2.17.tar.gz.md5} log4j-1.2.17.tar.gz.md5}} | {{{http://www.apache.org/dist/logging/log4j/1.2.17/log4j-1.2.17.tar.gz.asc} log4j-1.2.17.tar.gz.asc}} | *-------------------------+---------+----------+-----------+ -| Apache log4j 1.3alpha-8 (zip) | {{{http://www.apache.org/dyn/closer.cgi/logging/log4j/1.3alpha-8/apache-log4j-1.3alpha-8.zip} apache-log4j-1.3alpha-8.zip}} | {{{http://www.apache.org/dist/logging/log4j/1.3alpha-8/apache-log4j-1.3alpha-8.zip.md5} apache-log4j-1.3alpha-8.zip.md5}} | {{{http://www.apache.org/dist/logging/log4j/1.3alpha-8/apache-log4j-1.3alpha-8.zip.asc} apache-log4j-1.3alpha-8.zip.asc}} | +| Apache log4j 1.2.17 (zip) | {{{http://www.apache.org/dyn/closer.cgi/logging/log4j/1.2.17/log4j-1.2.17.zip} log4j-1.2.17.zip}} | {{{http://www.apache.org/dist/logging/log4j/1.2.17/log4j-1.2.17.zip.md5} log4j-1.2.17.zip.md5}} | {{{http://www.apache.org/dist/logging/log4j/1.2.17/log4j-1.2.17.zip.asc} log4j-1.2.17.zip.asc}} | *-------------------------+---------+----------+-----------+ - Please read {{{http://httpd.apache.org/dev/verification.html}Verifying Apache HTTP Server Releases}} - for more information on why you should verify our releases. + It is essential that you verify the integrity of the downloaded files using the PGP or MD5 signatures. + Please read {{{http://httpd.apache.org/dev/verification.html}Verifying Apache HTTP Server Releases}} for more + information on why you should verify our releases. + + The PGP signatures can be verified using PGP or GPG. First download the {{{http://www.apache.org/dist/logging/KEYS}KEYS}} + as well as the asc signature file for the relevant distribution. Make sure you get these files from the + {{{http://www.apache.org/dist/logging/}main distribution directory}}, rather than from a mirror. Then verify the signatures using + +--- +% gpg --import KEYS +% gpg --verify log4j-1.2.17.tar.gz.asc +--- + + Apache log4j 1.2.17 is signed by Christian Grobmeier 42196CA8 + + Alternatively, you can verify the MD5 signature on the files. A unix program called md5 or md5sum is included + in many unix distributions. + * Previous Releases diff --git a/src/site/apt/index.apt b/src/site/apt/index.apt index ce0ef06b9e..d06334d105 100644 --- a/src/site/apt/index.apt +++ b/src/site/apt/index.apt @@ -12,14 +12,86 @@ ~~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~~ See the License for the specific language governing permissions and ~~ limitations under the License. - ------ - log4j 1.3 - ------ - ------ - ------ - - Active development of log4j 1.3 has been suspended in - preference for development of log4j 2.0 targeting Java 5 - and higher. Many features originally developed during - the log4j 1.3 development effort have been backported - and packaged as companions which can work with log4j 1.2. + +Apache log4j\u2122 1.2 + + Welcome to Apache log4j, a logging library for Java. Apache log4j + is an Apache Software Foundation Project and developed by a dedicated + team of Committers of the Apache Software Foundation. + For more info, please see {{{http://www.apache.org}The Apache Software Foundation}}. + Apache log4j is also part of a project which is known as {{{http://logging.apache.org}Apache Logging}}. + Please see the {{{/license.html}License}}. + + If you are interested in the recent changes, visit our {{{/changes-report.html}changes report}}. + +* Why logging? + + Inserting log statements into your code is a low-tech method + for debugging it. It may also be the only way because + debuggers are not always available or applicable. This is + often the case for distributed applications. + + On the other hand, some people argue that log statements + pollute source code and decrease legibility. (We believe that + the contrary is true). In the Java language where a + preprocessor is not available, log statements increase the + size of the code and reduce its speed, even when logging is + turned off. Given that a reasonably sized application may + contain thousands of log statements, speed is of particular + importance. + +* Why log4j? + + With log4j it is possible to enable logging at runtime + without modifying the application binary. The log4j package is + designed so that these statements can remain in shipped code + without incurring a heavy performance cost. Logging behavior + can be controlled by editing a configuration file, without + touching the application binary. + + Logging equips the developer with detailed context for + application failures. On the other hand, testing provides + quality assurance and confidence in the application. Logging + and testing should not be confused. They are + complementary. When logging is wisely used, it can prove to be + an essential tool. + + One of the distinctive features of log4j is the notion of + inheritance in loggers. Using a logger + hierarchy it is possible to control which log + statements are output at arbitrarily fine granularity but also + great ease. This helps to reduce the volume of logged output and + the cost of logging. + + The target of the log output can be a file, an + OutputStream, a java.io.Writer, a + remote log4j server, a remote Unix Syslog daemon, or many other output targets. + +* Performance + + On an AMD Duron clocked at 800Mhz running JDK 1.3.1, it costs + about 5 nanoseconds to determine if a logging statement should + be logged or not. Actual logging is also quite fast, ranging + from 21 microseconds using the SimpleLayout, 37 + microseconds using the TTCCLayout. The performance of the + PatternLayout is almost as good as the dedicated layouts, + except that it is much more flexible. + +* Roadmap + + The package is being constantly improved thanks to input from + users and code contributed by authors in the community. + + Please note, the team is currently working on log4j 2 which will replace + log4j 1 in near future. + +* Get involved + + We are glad about help! Please make sure you have read the + {{{http://www.apache.org/foundation/getinvolved.html}Get Involved}} document. + Then join the {{{http://logging.apache.org/log4j/1.2/mail-lists.html}dev mailinglist}} + and fix issues from {{{https://issues.apache.org/bugzilla/describecomponents.cgi?product=Log4j}Bugzilla}}. + + You can obtain the code via {{{source-repository.html}SVN}} or our {{{http://git.apache.org/log4j.git/}Git mirror}}. + + diff --git a/src/site/apt/roadmap.apt b/src/site/apt/roadmap.apt index 7c35eaa12b..13c60d435c 100644 --- a/src/site/apt/roadmap.apt +++ b/src/site/apt/roadmap.apt @@ -12,16 +12,11 @@ ~~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~~ See the License for the specific language governing permissions and ~~ limitations under the License. - ------ - log4j 1.3 Roadmap - ------ - ------ - ------ -log4j 1.3 Roadmap +Apache log4j 1.2 Roadmap - Active development of log4j 1.3 has been suspended in - preference for development of log4j 2.0 targeting Java 5 - and higher. Many features originally developed during - the log4j 1.3 development effort have been backported - and packaged as companions which can work with log4j 1.2. + Apache log4j 1.2 is mature and widely deployed. Significant + changes are unlikely. Bug fixes and maintenance releases are not anticipated. + + The current version is {{{http://logging.apache.org/log4j/2.0/index.html}Apache log4j 2}} + diff --git a/src/site/fml/faq.fml b/src/site/fml/faq.fml index 546d8b6a21..b98a10e0da 100644 --- a/src/site/fml/faq.fml +++ b/src/site/fml/faq.fml @@ -41,7 +41,7 @@ arbitrary granularity.

    -

    log4j is designed with two three goals in mind: +

    log4j is designed with three goals in mind: reliability, speed and flexibility. There is a tight balance between these requirements. We believe that log4j strikes the right balance. @@ -73,9 +73,8 @@ What are the prerequisites for log4j? -

    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. +

    Log4j 1.2.8 and earlier are compatible with JDK 1.1.x and later, later versions + of log4j 1.2 are compatible with JDK 1.2 and later.

    The DOMConfigurator is based on the DOM Level 1 @@ -109,7 +108,7 @@

    log4j is based on a named logger hierarchy.

    -

    log4j is fail-stop. However, altough it certainly +

    log4j is fail-stop. However, although it certainly strives to ensure delivery, log4j does not guarantee that each log statement will be delivered to its destination.

    @@ -132,7 +131,7 @@ remote Unix Syslog daemon, to a remote listener using JMS, to the NT EventLog or even send e-mail.

    -

    log4j uses 5 levels, namely DEBUG, INFO, WARN, ERROR and +

    log4j uses 6 levels, namely TRACE, DEBUG, INFO, WARN, ERROR and FATAL.

    @@ -190,7 +189,7 @@ 262 [main] DEBUG SortAlgo.OUTER i=1 - Outer loop. 276 [main] DEBUG SortAlgo.SWAP i=1 j=0 - Swapping intArray[0] = 1 and intArray[1] = 0 290 [main] DEBUG SortAlgo.OUTER i=0 - Outer loop. -304 [main] INFO SortAlgo.DUMP - Dump of interger array: +304 [main] INFO SortAlgo.DUMP - Dump of integer 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. @@ -225,7 +224,7 @@ application.

    -

    The open and collaborative way in which log4j is developped +

    The open and collaborative way in which log4j is developed ensures that it continues to preserve and even widen its competitive edge. At some point, input from bright developers from all over the world is bound to make a difference. @@ -237,7 +236,7 @@ What are Loggers? -

    Lggers lie at the heart of log4j. Loggers define a hierarchy and give +

    Loggers lie at the heart of log4j. Loggers define a hierarchy and give the programmer run-time control on which statements are printed or not.

    @@ -299,8 +298,12 @@ l.debug("Entry number: " + i + " is " + String.valueOf(entry[i])); } +

    or using LogMF from the extras companion write

    +
    +    LogMF.debug(logger, "Entry number: {0} is {1}", i, entry[i]);
    +    
    -

    This way you will not incur the cost of parameter +

    This way you will not incur the cost of parameter construction if debugging is disabled for logger l. On the other hand, if the logger is debug enabled, you will incur the cost of evaluating whether the @@ -474,7 +477,7 @@ public class Foo { NTEventLogAppender? -

    Unfotunately, the logger names are hardcoded within the +

    Unfortunately, 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 @@ -542,7 +545,7 @@ public class Foo { there a method to remove logger instances?

    It is quite nontrivial to define the semantics of a - "removed" logger escecially if it is still referenced by the + "removed" logger especially if it is still referenced by the user. Future releases may include a remove method in the Logger class.

    @@ -559,7 +562,7 @@ public class Foo {

    - How about the timesamps of events generated by multiple + How about the timestamps of events generated by multiple processes across multiple hosts (possibly across multiple timezones)? @@ -574,24 +577,26 @@ public class Foo {

    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 + or creating the log file. Note that because the clocks of various machines may not be synchronized, there may be timestamp inconsistencies between events generated on - different hosts. -

    + different hosts. The EnhancedPatternLayout in the extras companion + supports explicit specification of the timezone using a pattern like + "%d{HH:mm}{GMT}". +

    Why can't log4j find my properties file in a J2EE or WAR application?

    The short answer: the log4j classes and the properties file - are not within the scope of the same classloader. + are not within the scope of the same class loader.

    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 + the way class loading works with the release of Java 2. In + Java 2, class loaders are arranged in a hierarchical + parent-child relationship. When a child class loader needs to find a class or a resource, it first delegates the request to the parent.

    @@ -618,7 +623,7 @@ public class Foo {

    Because the configureAndWatch launches a - separate wathdog thread, and because there is no way to stop + separate watchdog thread, and because there is no way to stop this thread in log4j 1.2, the configureAndWatch method is unsafe for use in J2EE envrironments where applications are recycled. @@ -777,5 +782,127 @@ public class Foo { logger name (or tree) for "audit" related messages.

    + + + Why does log4j throw a NullPointerException or + print a message about NOPLoggerRepository + when shutting down or restarting under Tomcat or during a shutdown + hook? +

    Tomcat will, by default, + clear all static members when unloading classes, however + this process can trigger initialization of classes which may + then call a class that has been cleared resulting in a + NullPointerException or some undesirable behavior. + Bug 40212) + describes the problem in detail and has a patch which at this writing + has not been applied to Tomcat. Glassfish had a similar problem + and accepted the patch.

    + +

    The following are recommended to avoid this problem: +

      +
    1. Set the org.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES + system property to false.
    2. +
    3. Apply the patch from bug 40212 + or upgrade to a version that has that patch applied.
    4. +
    5. Upgrade to log4j 1.2.16 or later to better defend against class loader attack + or provide a better diagnostic message when it does occur.
    6. +
    +

    + +

    It is impossible for log4j to defend against all attacks on + its internal state by a class loader. There is a limit to + the defensive measures that will be incorporated.

    + +

    For more background, see bugs + 40212, + 41939, + 43867, + 40159, + 43181, + 41316 and + 37956. +

    +
    +
    + + Why isn't my rolling file appender properly rolling files or why does + logging events get written to the old log file? + Most commonly this is due to multiple appenders attempting to + use the same file path and most likely by having multiple independent + instances of log4j read the same configuration file, however having the log file + open by another process (an editor, backup utility) can also interfere with rolling. + No provided file appender is reliable when multiple instances are writing to + the same file path and java.io provides no mechanism to coordinate writing + between JVM's. + + + + Why do I see a warning about "No appenders found for logger" and + "Please configure log4j properly"? + + + This occurs when the default configuration files log4j.properties and + log4j.xml can not be found and the application performs no explicit configuration. + log4j uses Thread.getContextClassLoader().getResource() to locate the default + configuration files and does not directly check the file system. + Knowing the appropriate location to place log4j.properties or log4j.xml + requires understanding the search strategy of the class loader in use. + log4j does not provide a default configuration since output to the console + or to the file system may be prohibited in some environments. Also see + FAQ: Why can't log4j find my properties in a J2EE or WAR application?. + + + + What system properties are checked by log4j? + +
    +
    log4j.debug
    +
    If true, log4j will output internal debugging messages to the console.
    +
    log4j.defaultInitOverride
    +
    If true, log4j will not perform default initialization, + that is check for log4j.properties or log4j.xml, at the first logging request.
    +
    log4j.configuration
    +
    URL for default initialization configuration file.
    +
    log4j.configurationClass
    +
    Class name for configurator to process default initialization configuration file.
    +
    log4j.ignoreTCL
    +
    If true, the thread class loader will be ignored when loading classes.
    +
    +

    The SMTPAppender may be influenced by mail.smtp and mail.smtps system properties.

    +
    +
    + + + How can I prevent memory leaks when using MDC? + + + The following message sometimes comes up in combination with MDC: + +
    +[webapp] created a ThreadLocal with key of type [org.apache.log4j.helpers.ThreadLocalMap] (value [org.apache.log4j.helpers.ThreadLocalMap@f6af3b]) and a value of type [java.util.Hashtable] (value [{userId=jo2372}]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
    +          
    + + In this case MDC is not cleaned up properly. Since log4j 1.2.17 the clear()-Method is called when the last + key of the underlying ThreadLocalMap is removed. To prevent the error message above, + the application need to take care it self of removing the keys which are not longer necessary. + + With web applications one can do this with creating a Servlet Filter and overriding the doFilter method: + +
    +try {
    +    MDC.put(myKey);
    +    chain.doFilter(request, response);
    +} finally {
    +    MDC.remove(myKey);
    +}          
    +          
    + + Please note, cleaning up the MDC in the Servlets destroy method might not lead to the desired results, + as destroy is not necessary called from the Thread which is holding the the map. + + For more information please also see: https://issues.apache.org/bugzilla/show_bug.cgi?id=50486 +
    +
    + diff --git a/src/site/resources/css/maven-base.css b/src/site/resources/css/maven-base.css new file mode 100644 index 0000000000..7ef9c54b1e --- /dev/null +++ b/src/site/resources/css/maven-base.css @@ -0,0 +1,168 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ +body { + margin: 0px; + padding: 0px; +} +img { + border:none; +} +table { + padding:0px; + width: 100%; + margin-left: -2px; + margin-right: -2px; +} +acronym { + cursor: help; + border-bottom: 1px dotted #feb; +} +table.bodyTable th, table.bodyTable td { + padding: 2px 4px 2px 4px; + vertical-align: top; +} +div.clear{ + clear:both; + visibility: hidden; +} +div.clear hr{ + display: none; +} +#bannerLeft, #bannerRight { + font-size: xx-large; + font-weight: bold; +} +#bannerLeft img, #bannerRight img { + margin: 0px; +} +.xleft, #bannerLeft img { + float:left; +} +.xright, #bannerRight { + float:right; +} +#banner { + padding: 0px; +} +#banner img { + border: none; +} +#breadcrumbs { + padding: 3px 10px 3px 10px; +} +#leftColumn { + width: 170px; + float:left; + overflow: auto; +} +#bodyColumn { + margin-right: 1.5em; + margin-left: 197px; +} +#legend { + padding: 8px 0 8px 0; +} +#navcolumn { + padding: 8px 4px 0 8px; +} +#navcolumn h5 { + margin: 0; + padding: 0; + font-size: small; +} +#navcolumn ul { + margin: 0; + padding: 0; + font-size: small; +} +#navcolumn li { + list-style-type: none; + background-image: none; + background-repeat: no-repeat; + background-position: 0 0.4em; + padding-left: 16px; + list-style-position: outside; + line-height: 1.2em; + font-size: smaller; +} +#navcolumn li.expanded { + background-image: url(../images/expanded.gif); +} +#navcolumn li.collapsed { + background-image: url(../images/collapsed.gif); +} +#poweredBy { + text-align: center; +} +#navcolumn img { + margin-top: 10px; + margin-bottom: 3px; +} +#poweredBy img { + display:block; + margin: 20px 0 20px 17px; +} +#search img { + margin: 0px; + display: block; +} +#search #q, #search #btnG { + border: 1px solid #999; + margin-bottom:10px; +} +#search form { + margin: 0px; +} +#lastPublished { + font-size: x-small; +} +.navSection { + margin-bottom: 2px; + padding: 8px; +} +.navSectionHead { + font-weight: bold; + font-size: x-small; +} +.section { + padding: 4px; +} +#footer { + padding: 3px 10px 3px 10px; + font-size: x-small; +} +#breadcrumbs { + font-size: x-small; + margin: 0pt; +} +.source { + padding: 12px; + margin: 1em 7px 1em 7px; +} +.source pre { + margin: 0px; + padding: 0px; +} +#navcolumn img.imageLink, .imageLink{ + padding-left: 0px; + padding-bottom: 0px; + padding-top: 0px; + padding-right: 2px; + border: 0px; + margin: 0px; +} diff --git a/src/site/resources/css/site.css b/src/site/resources/css/site.css new file mode 100644 index 0000000000..1e70f6cbcd --- /dev/null +++ b/src/site/resources/css/site.css @@ -0,0 +1,17 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ diff --git a/src/site/resources/images/ls-logo.jpg b/src/site/resources/images/ls-logo.jpg index 611c5c3654..35f2f4738b 100755 Binary files a/src/site/resources/images/ls-logo.jpg and b/src/site/resources/images/ls-logo.jpg differ diff --git a/src/site/resources/images/maven-feather.png b/src/site/resources/images/maven-feather.png new file mode 100644 index 0000000000..b5ada836e9 Binary files /dev/null and b/src/site/resources/images/maven-feather.png differ diff --git a/docs/od.gif b/src/site/resources/images/od.gif similarity index 100% rename from docs/od.gif rename to src/site/resources/images/od.gif diff --git a/src/site/site.xml b/src/site/site.xml index 58f1085fcd..5828916688 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -15,62 +15,73 @@ limitations under the License. --> - - - Apache Logging Services Project - images/ls-logo.jpg - http://logging.apache.org/ - - - Apache log4j - images/logo.jpg - http://logging.apache.org/log4j - - - - - - - - - - - - - - + + + org.apache.maven.skins + maven-fluido-skin + 1.2.1 + + + + false + true + true + + + + Apache Logging Services Project + images/ls-logo.jpg + http://logging.apache.org/ + + + Apache log4jâ„¢ + images/logo.jpg + http://logging.apache.org/log4j + + + + + + + + - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Apache log4j, Apache Extras Companion for Apache log4j, Apache, the Apache feather logo, + the Apache Logging Services project logo, the log4j logo, and the Built by Maven logo are + trademarks of The Apache Software Foundation. Oracle and Java are registered trademarks of Oracle and/or its affiliates. + Other names may be trademarks of their respective owners.

    +
    + diff --git a/src/site/xdoc/building.xml b/src/site/xdoc/building.xml new file mode 100644 index 0000000000..eabe120309 --- /dev/null +++ b/src/site/xdoc/building.xml @@ -0,0 +1,227 @@ + + + + + The Apache log4j team + How to build Apache log4j + + +
    + +

    Introduction

    + +

    This is a detailed instruction to reproduce the log4j distribution +either to verify that the release is reproducable or to prepare +a hot-fix.

    + +

    The log4j build is platform dependent. The best is to setup a VM using virtualbox (or similar), +install Ubuntu and follow the steps here.

    + +

    Preparation of environment

    + +

    Install Sun Java 6

    +
    +$> sudo sed  's/restricted/restricted universe multiverse/' -i /etc/apt/sources.list
    +$> sudo apt-get update && sudo apt-get -y update
    +$> sudo apt-get install openjdk-6-jdk
    +
    + + +

    Install Maven 2, Subversion, mingw and xemacs21, openssh-server:

    + +
    +$> sudo apt-get install maven2 subversion mingw32 xemacs21 openssh-server
    +
    + +

    Copy Win32 version of jni_md.h for NTEventLogAppender.dll

    + +
    +c:\>cd "\Program Files\Java\jdk_1.6.0_16\include\win32
    +c:\>scp jni_md.h username@hostname:
    +
    +$> export JNI_WIN32_INCLUDE_DIR=/home/username
    +
    + +

    Signing & Deploying

    + +

    Create a local ssh key with no passphrase to enable +"deployment" of site back to the local machine using scp.

    + +
    +$> ssh-keygen
    +$> cd ~/.ssh
    +$> cat id_rsa.pub >> authorized_keys
    +$> ssh localhost
    +$> exit
    +
    + +

    It's important to add localhost and people.a.o to the list of permanent allowed hosts. +Besides the above, this should have been runned at least once:

    + +
    +$> ssh people.apache.org
    +
    + +

    If you intended to deploy jars to the repo or update the site, +you need to set up ssh to use private keys to access people.apache.org +and create or modify ~/.m2/settings.xml to specify user name and key location. +

    + +
    +<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
    +          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    +          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 
    +              http://maven.apache.org/xsd/settings-1.0.0.xsd">
    +   <servers>
    +    <server>
    +      <id>logging.repo</id>
    +      <username>USERNAME for people.apache.org</username>
    +      <privateKey>/home/username/.ssh/id_rsa</privateKey>
    +      <passphrase></passphrase>
    +    </server>
    +   </servers>
    +</settings>
    +
    + +

    You should test your ssh connection to people.apache.org +and localhost before attempting a deployment like:

    + +
    +$ ssh -l USERNAME people.apache.org
    +$ ssh localhost
    +
    + +

    Building release artifacts

    + +

    Before you build, please make sure you have a nonblocking editor set as SVN editor. Like:

    + +
    +$ export SVN_EDITOR=xemacs
    +
    + +

    Other checks:

    + +
      +
    • Please make sure changes.xml reflect all fixed issues. The release date in changes is to be set + to the date the release candidate is created.
    • +
    • Please update doap_log4j.rdf to reflect the correct version. Use the same release date as in changes.
    • +
    +

    The release artifacts were originally built by:

    + +
    +$> svn co http://svn.apache.org/repos/asf/logging/log4j/trunk log4j
    +$> cd log4j
    +$> mvn package release:prepare
    +$> mvn release:perform
    +
    + +

    Note: you'll be ask for a SVN tagname. Please use the following pattern: v1.2.17-RC1.

    + +

    +Attention: this is an non-interactive build. In some cases it is necessary +to add: -Dusername=paouser -Dpassword=paopassword +to the release plugin commands. This is surely not safe because your password +can be seen clearly. +

    + +

    Sometimes iz might be necessary to disable keystore on Ubuntu machines when the automatic svn commit fails. To do this, add the following line to .subversion/config in your [auth] section:

    + +
    password-stores =
    + +

    The release artifacts can be rebuilt by:

    + +
    +$ mvn release:perform -DconnectionUrl=scm:svn:https://svn.apache.org/repos/asf/logging/log4j/tags/v1_2_16
    +
    + +

    ATTENTION: if your asc files are not created, you need to create them manually. F. e.

    + +
    +    #!/bin/sh
    +
    +    if [ -n "$1" ]
    +    then
    +      root_dir=$1
    +    else
    +      root_dir=.
    +    fi
    +
    +    for file in $root_dir/*.jar $root_dir/*.pom $root_dir/*.zip $root_dir/*.tar.gz; do
    +       echo §file
    +        gpg --armor --output $file.asc --detach-sig $file
    +        echo "GPG verification output"
    +        gpg --verify $file.asc $file
    +        echo "~~~~~~~~~~~~~~~~~~~~~~~"
    +    done
    +
    + + +

    Building site and artifacts from a tag:

    + +
    +$ svn co https://svn.apache.org/repos/asf/logging/log4j/tags/v1_2_16
    +$ cd v1_2_16
    +$ mvn site assembly:assembly
    +
    + +

    TODO: the following section describes site staging. This must be altered: the staging must not happen in SVN.

    + +

    +The website content will automatically be staged to the ASF SVN repo by "mvn site-deploy". +This phase checks out https://svn.apache.org/repos/asf/logging/site/trunk/docs/log4j/1.2 +into target/site-deploy, copys the generated documentation to that directory using +scp to localhost and then commits the changed content. You will be prompted for an +SVN commit message using the configured SVN_EDITOR. A commit message must be entered or the +site commit will be aborted. +

    + +

    +The staged content can be tested by opening +http://svn.apache.org/repos/asf/logging/site/trunk/docs/1.2/index.html, +however some links may be broken due to the staged location. +The staged version can be published to the main public site by executing +"svn update" in /www/logging.apache.org/log4j/1.2 on people.apache.org. +

    + +

    If a vote has failed

    +
      +
    • Send a "cancel" note to the mailinglist (usually resend the vote mail with [CANCEL] in subject
    • +
    • Delete the RC artifacts from:
      http://people.apache.org/builds/logging/repo/log4j/log4j/
    • +
    + + + +

    If a vote has passed

    + +

    If a RC has passed the vote, these steps are necessary:

    + +

    Rename the tag:

    +
    +$> svn mv https://svn.apache.org/repos/asf/logging/log4j/tags/log4j-1.2.17-RC1 https://svn.apache.org/repos/asf/logging/log4j/tags/log4j-1.2.17
    +
    + +

    mv the tar.gz and the zip files to p.a.o dist

    +

    Create a jar file containing your artifacts: jar cf log4j-bundle-1217.jar *

    +

    Upload the bundle to repository.apache.org and follow the instructions to get the artifacts from staging to proper

    + +

    Send an announcement to: announce@apache.org, general@logging.apache.org, log4j-dev@logging.apache.org, log4j-user@logging.apache.org

    + +
    + +
    \ No newline at end of file diff --git a/src/site/xdoc/manual.xml b/src/site/xdoc/manual.xml index 0806f758bd..8134287876 100644 --- a/src/site/xdoc/manual.xml +++ b/src/site/xdoc/manual.xml @@ -56,7 +56,7 @@ href="http://www.semper.org">SEMPER project decided to write its own tracing API. This was in early 1996. After countless enhancements, several incarnations and much work that API has evolved to become log4j, a popular logging package for Java. The package is distributed -under the Apache Software License, a +under the Apache Software License, a fully-fledged open source license certified by the open source initiative. The latest log4j version, including full-source code, class files and @@ -71,7 +71,7 @@ always available or applicable. This is usually the case for multithreaded applications and distributed applications at large.

    Experience indicates that logging was an important component of the -development cycle. It offeres several advantages. It provides precise +development cycle. It offers several advantages. It provides precise context about a run of the application. Once inserted into the code, the generation of logging output requires no human intervention. Moreover, log output can be saved in persistent medium @@ -161,7 +161,7 @@ is exceptional in two ways: href="apidocs/org/apache/log4j/Logger.html#getRootLogger()">Logger.getRootLogger method retrieves it. All other loggers are instantiated and retrieved with the class static Logger.getLogger +href="apidocs/org/apache/log4j/Logger.html#getLogger(java.lang.String)">Logger.getLogger method. This method takes the name of the desired logger as a parameter. Some of the basic methods in the Logger class are listed below.

    @@ -268,7 +268,7 @@ other loggers X, X.Y and

    In example 2, all loggers have an assigned level value. There -is no need for level inheritence.

    +is no need for level inheritance.

    @@ -307,14 +307,14 @@ having an assigned level..

    of a logger instance. These printing methods are -debug, +debug, -info, +info, -warn, -error, -fatal - and log.

    +warn, +error, +fatal + and log.

    By definition, the printing method determines the level of a @@ -443,7 +443,7 @@ daemons. It is also possible to log addAppender +href="apidocs/org/apache/log4j/Category.html#addAppender(org.apache.log4j.Appender)">addAppender method adds an appender to a given logger. Each enabled logging @@ -457,7 +457,7 @@ console. If in addition a file appender is added to a logger, say C's children will print on a file and on the console. It is possible to override this default behavior so that appender accumulation is no longer additive by setting +href="apidocs/org/apache/log4j/Category.html#setAdditivity(boolean)">setting the additivity flag to false.

    The rules governing appender additivity are summarized below.

    @@ -476,7 +476,7 @@ the additivity flag to false.

    However, if an ancestor of logger C, say P, has the additivity flag set to false, then C's output will be directed to all the appenders in - C and it's ancestors upto and including P but + C and its ancestors upto and including P but not the appenders in any of the ancestors of P.

    Loggers have their additivity flag set to @@ -553,7 +553,7 @@ your current project, then you can register an needs to be logged.

    Object rendering follows the class hierarchy. For example, assuming -oranges are fruits, if you register an FruitRenderer, all +oranges are fruits, if you register a FruitRenderer, all fruits including oranges will be rendered by the FruitRenderer, unless of course you registered an orange specific OrangeRenderer.

    @@ -710,7 +710,7 @@ version.

    PropertyConfigurator to parse a configuration file and set up logging accordingly.

    -

    Here is a sample configuration file that results in exactly same +

    Here is a sample configuration file that results in identical output as the previous BasicConfigurator based example.

    Logger
    name
    Assigned
    level
    - - - - - - - - - - - - - - - - - - - - - - o.a.l. - - - - \ No newline at end of file diff --git a/src/xdocs/stylesheets/lf5.xml b/src/xdocs/stylesheets/lf5.xml deleted file mode 100644 index de5263e7e8..0000000000 --- a/src/xdocs/stylesheets/lf5.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - Log4j project - LogFactor5 - - - - - - - - - - - - - - - - - - - - - diff --git a/src/xdocs/stylesheets/project.xml b/src/xdocs/stylesheets/project.xml deleted file mode 100644 index 86f7c9767d..0000000000 --- a/src/xdocs/stylesheets/project.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - Log4j project - The log4j project - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/xdocs/stylesheets/site.vsl b/src/xdocs/stylesheets/site.vsl deleted file mode 100755 index bfd12ba0f0..0000000000 --- a/src/xdocs/stylesheets/site.vsl +++ /dev/null @@ -1,318 +0,0 @@ - - - - - ## Defined variables - #set ($bodybg = "#ffffff") - #set ($bodyfg = "#000000") - #set ($bodylink = "#525D76") - - #set ($titlebg = "#FFFFFF") - #set ($titlefg = "#2222AA") - - #set ($bannerbg = "#FFFFFF") - #set ($bannerfg = "#2222AA") - - #set ($subbannerbg = "#828DA6") - #set ($subbannerfg = "#ffffff") - - -#document() - - -## This is where the macro's live - -#macro ( projectanchor $name $value ) - #if ($value.startsWith("http://")) - $name - #else - $name - #end -#end - -#macro ( metaauthor $author $email ) - - -#end - -#macro ( image $value ) -#if ($value.getAttributeValue("width")) -#set ($width=$value.getAttributeValue("width")) -#end -#if ($value.getAttributeValue("height")) -#set ($height=$value.getAttributeValue("height")) -#end -#if ($value.getAttributeValue("align")) -#set ($align=$value.getAttributeValue("align")) -#end - -#end - -## ============================================ -## subsection macro -## ============================================ -#macro ( subsection $subsection) -

    $subsection.getAttributeValue("name")

    - #foreach ( $items in $subsection.getChildren() ) - #if ($items.getName().equals("img")) - #image ($items) - #elseif ($items.getName().equals("source")) - #source ($items) - ## #elseif ($items.getName().equals("table")) - ## #table ($items) - #else - $items - #end - #end -#end - -## =================================== -## titleSection macro -## =================================== -#macro ( titleSection $titleSection) - $titleSection.getAttributeValue("name") -#end - -## ================================ -## section macro -## ================================ -#macro ( section $section) -

    $section.getAttributeValue("name")

    - #foreach ( $items in $section.getChildren() ) - #if ($items.getName().equals("img")) - #image ($items) - #elseif ($items.getName().equals("source")) - #source ($items) - ##elseif ($items.getName().equals("table")) - ## #table ($items) - #elseif ($items.getName().equals("subsection")) - #subsection ($items) - #else - $items - #end - #end -#end - -## =================================== -## make navigation bar -## =================================== - -#macro ( makeNavigationBar ) - -
    - #set ($menus = $project.getChild("body").getChildren("menu")) - #foreach ( $menu in $menus ) - - #foreach ($item in $menu.getChildren() ) - #set ($name = $item.getAttributeValue("name")) - - #end - #end -
    - -#end - -## ==================================== -## getProjectImage -## ==================================== -#macro (getProjectImage) - ##
    @@ -815,7 +815,7 @@ forwarding the log event to a second log4j server.

    The log4j library does not make any assumptions about its environment. In particular, there are no default log4j appenders. Under certain well-defined circumstances however, the -static inializer of the Logger class will attempt to +static initializer of the Logger class will attempt to automatically configure log4j. The Java language guarantees that the static initializer of a class is called once and only once during the loading of a class into memory. It is important to remember that @@ -906,7 +906,7 @@ tells log4j to use the file foobar.txt as the default configuration file. This file should be place under the WEB-INF/classes directory of your web-application. The file will be read using the PropertyConfigurator. Each +href="apidocs/org/apache/log4j/PropertyConfigurator.html">PropertyConfigurator. Each web-application will use a different default configuration file because each file is relative to a web-application.

    diff --git a/src/xdocs/chainsaw.xml b/src/xdocs/chainsaw.xml deleted file mode 100644 index c41d856a41..0000000000 --- a/src/xdocs/chainsaw.xml +++ /dev/null @@ -1,135 +0,0 @@ - - - - - Paul Smith - Chainsaw v2 Documentation - - - -
    -

    Welcome to the home of Chainsaw v2!

    - -

    Chainsaw v2 is a companion application to Log4j written by members of the Log4j development - community. Like a number of Open Source - projects, this new version was built upon inspirations, ideas and creations of others. - Chainsaw v2 has it's roots from the original Chainsaw utility written by Oliver Burn, - and with inspiration from the Log Factor 5 utility contributed by ThoughtWorks Inc.

    -
    - -
    -

    Latest Build Date: 2006-03-02 (SVN tag 'release_20060302') -

    -

    -

    -

    -
    -
    - -
    - -
    -

     It's a GUI-based Log viewer. A picture tells a thousand words...

    - -

    -

    [zoom image]

    - -

    These screen shots were taken on Windows 2000, running Sun JDK 1.4.2.

    - -

    Rather than rely on a combination of tail/grep/vi or equivalent to view/query/trace-through - a huge trail of logging events, you can use Chainsaw. Chainsaw can read log files formatted in Log4j's XMLLayout, receive - events from remote locations, read events from a DB, it can even work with the JDK 1.4 logging events.

    - -
    - -
    -

      Heres just a brief run down of some of the features of Chainsaw v2:

    -
      -
    • View remote events - Remote events are "received" by Chainsaw using Log4j 1.3's new Receiver concept.
    • -
    • Saved Preferences - You can fully customize each Tab the way you want it, and it will restore it's state the next time.
    • - -
    • Responsive - When events are screaming in, you don't want the GUI to meltdown. You can control - how responsive the GUI is and determine the frequency of updates.
    • -
    • Tabs/Docking - Chainsaw routes separate applications/remote hosts' events to a unique Tab within the GUI. - These tabs can be undocked from the main window. Using these features you can manage multiple application logs using the one GUI.
    • -
    • Coloring - You can specify your own rules to color each event row depending on the attributes of a LoggingEvent to - help you locate important events.
    • -
    • Dynamic and powerful filtering - Helps you locate stuff. There's support for quick-and-dirty filtering, right through to advanced expression-based filtering (e.g. "LOGGER == 'com.mycompany' && LEVEL == ERROR" ).
    • -
    • Cyclic - A tab view can support a Cyclic-based model, which constrains it's view to the last - X events, ensuring you don't hog memory. This is great for monitoring live applications.
    • -
    • Built-in documentation and tutorial - HTML-based documentation included in the package.
    • -
    -
    - -
    -

     Chainsaw already includes help with - with a Quick Reference and a Tutorial to get you started, all viewable from within the GUI!. A User Manual will be made available around release time.

    -
    - -
    -

    Due to Java classloading rules, it is impossible to ship the Jakarta Commons VFS extension to Chainsaw - OR have DBReceiver or JMSReceiver bundled with Chainsaw. - Several VFS filestore implementation jars cannot be shipped with Chainsaw because of licensing issues, and for JMSReceiver and DBReceiver you are required - to have proprietary driver jars locally which we obviously can't ship. You can follow these steps to enable the DB, JMS and/or VFS components inside Chainsaw. -

      -
    1. [DBReceiver] Download the DB extension to Chainsaw
    2. -
    3. [JMSReceiver] Download the JMS extension to Chainsaw
    4. - -
    5. [VFS] Download the VFS extension to Chainsaw
    6. -
    7. [VFS] Download VFS
    8. -
    9. [VFS] Download Commons Logging Jars
    10. -
    11. [VFS] Download the VFS filestore implementation jars you wish to use
    12. - -
    13. Place all these jars in your .chainsaw/plugins directory (the .chainsaw directory is in your home directory)
    14. -
    15. Start Chainsaw, which should now recognize the existence of these components and allow you to use them.
    16. -
    -

    -

    This applies to all distributions.

    -
    - -
    -

    Chainsaw has ZeroConf elements embedded within it, but you'll need to add a few things - to your application to enable your application for ZeroConf.

    -

    Download:

    -
      -
    1. log4j ZeroConf extension
    2. -
    3. JmDNS bundle
    4. -
    5. Add the log4j-zeroconf.jar and the jmdns.jar from these bundles and add them to your - application's classpath.
    6. -
    7. Modify your log4j configuration so that it use the ZeroConfSocketHubAppender. Here is a complete log4j.xml file that you can use as a base: -
      -<log4j:configuration debug="false" threshold="debug"  xmlns:log4j="http://jakarta.apache.org/log4j/>
      -    <appender name="zeroconf" class="org.apache.log4j.net.ZeroConfSocketHubAppender">
      -        <param name="Name" value="MyZeroConfSockeHubAppender" />
      -    </appender>
      -    <!--ROOT Logger-->
      -    <root>
      -        <level value="INFO" />
      -        <appender-ref ref="zeroconf" />
      -    </root>
      -</log4j:configuration>
      -				
      -
    8. -
    -
    - -
    diff --git a/src/xdocs/codes.xml b/src/xdocs/codes.xml deleted file mode 100644 index 5b439ab91e..0000000000 --- a/src/xdocs/codes.xml +++ /dev/null @@ -1,151 +0,0 @@ - - - - - - Ceki Gülcü - Log4j error codes - - - - -
    -

    Log4j error messages and their meanings

    -

    Ceki Gülcü
    - November 2004, last updated on December 17th, 2004

    -
    - - - The 'log4j.dtd' is no longer used nor needed. - - -

    Given syntactical flexiblilty that - JoranConfigrator supports, it is no longer - possible to express this syntatical range with a DTD. Thus, - new log4j configuration files in XML should follow the general - template. -

    - -

    Good:

    - -
    <?xml version="1.0" encoding="UTF-8" ?>
    -<!DOCTYPE configuration>
    -
    -<configuration xmlns='http://logging.apache.org/'>
    -  ...
    -</configuration>
    -        
    - -

    However, JoranConfigurator will continue to - parse your old XML configuration files which previously - required a reference to log4j.dtd. Thus, altough - deprecated, the following form will continue to be parsed - correctly. -

    - -

    Deprecated:

    - -
    <?xml version="1.0" encoding="UTF-8" ?>
    -<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
    -
    -<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
    -  ...
    -</log4j:configuration>
    -        
    - - -

    Using this deprecated form will generate the above mentioned - error message along with an error from the XML parser. -

    - -
    -
    - - - - - The <b>FileNamePattern</b> option must be set before - using <code>TimeBasedRollingPolicy</code> or - <code>FixedWindowRollingPolicy</code>. - - - -

    The FileNamePattern option for both - TimeBasedRollingPolicy and - FixedWindowRollingPolicy is mandatory. -

    -
    - -
    - - - Could not find an appender named [XYZ]. Did you define it below in the config file? - - -

    Whereas the order of declatation of appenders did not - matter in log4j 1.2, in log4j version 1.3 and later, any - appender referenced at a given point must have been already - declared above that point. In practice though, only - configuration files declaring an AsyncAppender - may be affected by this change and only if the appenders - embeded in th AsyncAppender are declared below it - instead of being declared above it. -

    - -

    For example, the following config file will no longer work.

    - -

    Bad:

    - -
    <?xml version="1.0" encoding="UTF-8" ?>
    -<!DOCTYPE log4j:configuration>
    -
    -<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
    -
    -  <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
    -    <appender-ref ref="FILE" />
    -  </appender>
    -
    -   <appender name="FILE" class="org.apache.log4j.FileAppender">
    -    <param name="File" value="myapp.log"/>
    -    ...
    -  </appender>
    -
    -  <root>
    -    <level value ="debug" />
    -    <appender-ref ref="ASYNC" />
    -  </root>
    -
    -</log4j:configuration>
    -        
    - -

    It should be changed to the following form.

    - -

    Good:

    - -
    <?xml version="1.0" encoding="UTF-8" ?>
    -<!DOCTYPE configuration>
    -
    -<configuration xmlns='http://logging.apache.org/'>
    -
    -   <appender name="FILE" class="org.apache.log4j.FileAppender">
    -     <param name="File" value="myapp.log"/>
    -      ...
    -   </appender>
    -
    -  <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
    -    <appender-ref ref="FILE" />
    -  </appender>
    -
    -  <root>
    -    <level value ="debug" />
    -    <appender-ref ref="ASYNC" />
    -  </root>
    -</configuration>
    -        
    - - -
    - -
    - -
    \ No newline at end of file diff --git a/src/xdocs/contributors.xml b/src/xdocs/contributors.xml deleted file mode 100644 index b28c204088..0000000000 --- a/src/xdocs/contributors.xml +++ /dev/null @@ -1,168 +0,0 @@ - - - - - Ceki Gülcü - Log4j Contributors - - - -
    - -

    Log4j is the result of contributions from several dozen - developers and hundreds of users across the globe. Some of the - more prominent contributors are listed below in alphabetical - order. -

    -
      - - - - - -
    • Curt Arnold - -

      Curt is an independent software developer and current Logging Services PMC chair. - Curt developed the test framework for the W3C DOM test suites and has contributed to the - Apache Ant, Apache Xerces, Apache Batik, JSUnit, ArgoUML and ant-contrib - projects.

      -
    • - -
    • Mathias Bogaert - -

      While not lurking on the serverside, - Mathias mends the log4j documentation.

      -
    • - -
    • James P. Cakalic -

      Jim is the original author of the PatternLayout and the - NTEventLogAppender. -

      -
    • - -
    • Paul Glezen - -

      Paul maintains the log4j extension manual while he is not - consulting for IBM. -

      -
    • - -
    • Ceki Gülcü - - - - - -

      Ceki is the founder the log4j project which - continues to occupy much of his time. He enjoys writing - software altough he is discovering that it is far more - difficult than what it may seem initially. He is also - managing his IT services - company.

      -
    • - -
    • Jacob Kjome - -

      Jacob Kjome has been developing software - since 1997 and has been playing with Java for about 4 years. - Jake joined the log4j team after being very active on the - user list and contributing servlet and repository selector - related code to the logj-sandbox. He is also a committer on - the (non-Apache related) XMLC, BarracudaMVC, and Prevayler - projects. Of late his free time has been squeezed with a - new job and his vigorous 2 year old son, Nicholas, but he - still tries to pitch in when he can. :-) -

      -
    • - - -
    • Anders Kristensen - -

      Contributor of many enhancements, Anders takes a keen - interest in log4j and all things Java, OO, and XML. He is - currently specification lead for JSR 116, the SIP Servlet - expert group. -

      -
    • - -
    • Jim Moore -

      Jim is often seen answering tough question from log4j - users. -

      -
    • - -
    • Yoav Shapira - - - - -
      -

      Yoav Shapira works for Millennium Pharmaceuticals and - is as interested in the business aspects of Open-Source - Software as he is in the technical aspects. Yoav contributes - to the Tomcat container, the Log4j logging system, and a - number of jakarta-commons and other open-source projects. -

      -
      -
    • - -
    • Jon Skeet - -

      Jon is a software developer in his mid-twenties living in - the UK. He is a Java enthusiast and very active participant - in the comp.lang.java.* newsgroups as well as a moderator - for the log4j mailing lists. He is a committer for the Ant - project, involved (when time permits!) in tidying up the - code documentation. -

      -
    • - -
    • Paul Smith - - - - -
      -

      Paul Smith has been developing software since 1990, and playing - computer games a few years longer than that. He has been thoroughly - enjoying Java since 1998 after he gave up on Visual Basic in disgust. - Paul joined the log4j team after finding how darn useful it and the - companion Chainsaw application was in '03, and has been helping out - where he can, working on Chainsaw v2, and generally making a good - nuisance of himself. -

      - - -
    • - - -
    • Chris Taylor - -

      Chris is the author NTEventLogAppender. In around 1832, - he ported our previous GNU-make build system to at the time - unknown but promising jakarta-ant. -

      -
    • - -
    • Mark Womack - - - - - -
      -

      Mark Womack has been developing software for over 13 - years. He has been developing in Java for the past 5 years, - focusing on web application development. He has been an - active committer for the log4j project since April 2002, contributing - features for the upcoming v1.3 release. He is also a member of the Logging - Services PMC.

      -
      -
    • -
    -
    - - -
    \ No newline at end of file diff --git a/src/xdocs/documentation.xml b/src/xdocs/documentation.xml deleted file mode 100644 index 2209a1c7b8..0000000000 --- a/src/xdocs/documentation.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - - - Ceki Gülcü - Yoav Shapira - Documentation - - - - -
    - - - -
    - -
    - -
    - - -
    - -
    - -
    - -
    - - -
    -

    The following organisations offer log4j-related consultancy - and training services. Their inclusion on this page does - not imply endorsement by the Apache Software Foundation. -

    - - - - - -

    If you would like your log4j-related article or service - to be listed here, then please send a note to the log4j-user@logging.apache.org - list. -

    -
    - - -
    - diff --git a/src/xdocs/download.xml b/src/xdocs/download.xml deleted file mode 100644 index fd702fac51..0000000000 --- a/src/xdocs/download.xml +++ /dev/null @@ -1,378 +0,0 @@ - - - - - Ceki Gülcü - Download - - - - - -
    -

    Log4j is available - for download from a number of mirrors. Please - use these mirrors as they improve download time and save - bandwidth. -

    - -

    Changes in log4j 1.2.14: -

      -
    • AsyncAppender was rewritten to eliminate reported deadlocks (bugs 26224, 28006, 37904, 38137), - and to add an option to not block if the event queue becomes full (bug 38982).
    • - -
    • SyslogAppender can now accept a port specification (bug 39687) in its syslogHost attribute.
    • - -
    • SMPTAppender can now accept cc and bcc addresses (bug 19125) and perform password authentication (bug 24969).
    • - -
    • The following bugs were fixed: -
        -
      • 40159: NullPointerException in org.apache.log4j.NDC.get. -
      • 36787: org.apache.log4j.lf5.util.DateFormatManager.setTimeZone assignment error. -
      • 38559: Monthly logs not generated at midnight with DailyRollingFileAppender. -
      • 40145: PatternLayout specifier %r is not consistent with documentation. -
      • 37119: Space after log level causes default level to be used. -
      • 39135: Bad patterns in ISO8601DateFormat and DateTimeDateFormat. -
      • 35743: SyslogAppender throws NullPointerException upon misconfiguration. -
      • 15501: FallbackErrorHandler throws NullPointerException if no loggers are set. -
      • 38564: Bad documentation for WriterAppender.encoding. -
      • 37866: NTEventLogAppender not build, tested and placed in distribution. -
      • 38662: SMTPAppender does not output newlines between stack trace lines. -
      • 30294: SMTPAppender will not run within sandbox. -
      • 16922: MDC with SMTPAppender doesn't work. -
      • 31507: Misspelling in HierarchyDynamicMBean. -
      • 35123: Additivity not exported by PropertyPrinter. -
      • 31003: RollingFileAppender, if removed, can cause NullPointerExceptions. -
      • 23021: AsyncAppender blocks on thread death. -
      • 40412: NOTICE file added to distribution and jar. -
      • 40378: Chainsaw of log4j 1.2 does not show TRACE level. -
      • 40501: TRACE level missing in short introduction to log4j. -
      • 37960: Update site generation to velocity 1.4 and remove dependency on logging/site project. -
      -
    • -
    -

    - -

    The next major release of log4j will be version 1.3. It will contain - many new features and changes, and if you have written custom code, it may - need to be modified to work with it. Please see the document entitled preparing - for log4j 1.3 for a more detailed discussion. -

    - - - - -

    We also maintain earlier - versions of log4j for download, intended for the - curious paleontologist -- there seems to be quite a few - of them! -

    -
    - -
    - - -
    - -
    - - -
    DatedFileAppender
    - -
    DatedFileAppender works in the same manner as - the Tomcat FileLogger. Contrary to - DailyRollingFileAppender shipping with log4j, log - file names generated by DatedFileAppender always - contain today's date. While this distinction seems minor, it - means you can reliably copy, compress, remove or manipulate a - day's log file shortly after midnight. With the - DailyRollingFileAppender, a day's log file is not - renamed until the first message is logged some time after - midnight. -
    - - - -
    - JDBCAppender -
    - -
    A powerful JDBCAppender by Danko Mannhaupt - who continues the work of Thomas Fenner. You might find - this JDBCAppender more suitable then the one that ships with - log4j 1.2. -
    - - - -
    - Just4log -
    - -
    Just4Log is a library to enhance dynamically the - performance of various logging systems inside a java - application. Dynamically because the sourcecode in java is not - modified but rather the optimization occurs on the compiled - ByteCode files. -
    - - -
    log4Ant
    - -
    log4Ant includes a complete bridge to the Log4J logging systemfor a robust build monitoring system. - These Ant components let you capture, map, and send Ant log messages and stdio output through your Log4J installation. Contact contact@jware.info -
    - - -
    log4j400
    - -
    Log4J400 includes MessageQueue and DataQueue Appenders for - the AS/400 (aka IBM iSeries). -
    - - - -
    log4j2db
    - -
    This Project provides a set of EJBs to store Log4J events - (received via JMS appender) in a database. The main aim is to - provide a toolset for a centralized, data-center suitable - logging. -
    - - - -
    log4jME
    - -
    Log4jME, or log4j MiniEdition, is based on the - same code as log4j. However, as the name indicates the - mini-edition is much smaller. It offers the same client - interface such that code compiled for log4jME is - compatible with log4j standard edition. You can choose to - upgrade to log4j standard edition at any time by replacing - log4jME.jar with log4j.jar in your - classpath. At this time, log4jME is only available through - ASF Subversion repository in the Logging Services Sandbox. -
    - - - -
    log4Unit
    - -
    Log4Unit is a JUnit extension - combining JUnit with Log4J. The intention is to create test - protocols for JUnit. - -

    JUnit is asymmetrical in the sense that it focusses on the - documentation of test failures and errors. Successful - execution of a test case is not further documented. In order - to obtain a test protocol that documents the initial settings, - the test case execution and its results, a logging component - is required. Log4J as the current de facto standard is - selected for this extension. -

    -
    - - - -
    Log4Web (commercial)
    - -
    Log4Web is a J2EE web application, designed to web-enable - system log files that have been generated by log4j. -
    - - - -
    - Log Tag -
    -
    A custom log tag library from the Jakarta - Taglibs project.
    - - - -
    LogWeb
    - -
    LogWeb is a web interface for configuring log4j at runtime - within a servlet container. Every log4j feature of is - configurable through this interface. -
    - - - - -
    - SNMPTrapAppender -
    - -
    An appender to send formatted logging event strings to a - specified managment host (typically, a MLM of some sort, but - could also be an SNMP management console) in the form of an - SNMP trap. -
    - - - -
    XpoLog -
    - -
    Log view and analysis application which enables web - browsing and analysis over logs. -
    - - - -
    -
    - -
    - - - -
    - - -
    log4cxx
    -
    Log4cxx is a port to C++ of the log4j project.
    - - -
    log4net
    - -
    The .NET implementation of the popular log4j Java API - providing flexible and arbitrarily granular control over log - management and configuration.
    - - -
    log4php
    - -
    Log4Php is a PHP port of log4j framework. It supports xml configuration, - logging to files, stdout/err, syslog, socket, configurable - output layouts and logging levels.
    - -
    -
    - - -
    - -
    log4c
    - -
    ANSI C functions and macros for flexible logging to files - and other destinations. It is modeled after log4j. It follows - the log4j API within the limits of reason. Intended for use in time-space - critical environments.
    - - - -
    log4cpp
    -
    A library of C++ classes for flexible logging to files, - syslog, IDSA and other destinations modeled after log4j.
    - - - -
    log4cplus
    -
    Log4cplus is a simple to use C++ logging API providing - thread-safe, flexible, and arbitrarily granular control over - log management and configuration. It is modeled after the Java - log4j API.
    - - - -
    log4E
    - -
    The Goanna project (Eiffel Web Services) now includes - log4E, a complete port of log4j. -
    - - -
    Log::Log4perl
    - -
    Log::Log4perl is a Perl port of log4j by Kevin Goess and - Mike Schilli. The authors made sure that their port was as - close as possible to the original implementation. Even the - configuration files are similar! The project is still being - enhanced, however the current release is stable and has been - released to CPAN. -
    - - -
    log4LS
    - -
    Log4LS is a LotusScript library package and is used to get - logging statements to a Domino database, sent by mail or - written to a file. It is modeled after Jakarta log4j. -
    - - -
    log4py
    - -
    Log4Py is a python logging module similar to log4j. It - supports logging to files or to stdout/stderr, variable - log-levels, configurable output formats and configuration via - configuration files. -
    - - - -
    log4p
    -
    Another Python translation of log4j. This project no - longer seems to be maintained.
    - - - -
    log4plsql
    - -
    Log4plsql is a Oracle PL/SQL logging module similar to - log4j. It supports logging out-off transaction. It is useful - for logging, benchmarking and monitoring PL/SQL applications. -
    - - - -
    qmmslog
    - -
    Qmmslog is a port of log4j to the Qt/C++ platform. -
    - - -
    log4r
    -
    A Powerful Logger for Ruby. -

    Log4r features an extremely flexible logging library for - Ruby. Killer features include a heiarchial logging system - of any number of levels, logger inheritance, multiple - output destinations, tracing, custom formatting and more. - Log4r was inspired by log4j. Log4r provides the defining - features of log4j and some of its own features that just - might make log4j users envious.

    -
    - - -
    - -
    - -

    If you would like your software to be listed here, then send a note to the log4j-user@logging.apache.org - list.

    - -
    - - -
    \ No newline at end of file diff --git a/src/xdocs/earlier.xml b/src/xdocs/earlier.xml deleted file mode 100644 index 8edc59a419..0000000000 --- a/src/xdocs/earlier.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - Ceki Gülcü - Older distributions - - - - -
    - -
    - -

    BEWARE:Certain Internet Explorer versions rename .tar.gz downloads - as .tar. You should rename the files back to - tar.gz after the download completes. -

    -
    - - Log4j Archives - -
    - - -
    - diff --git a/src/xdocs/faq.xml b/src/xdocs/faq.xml deleted file mode 100644 index 4261a1193c..0000000000 --- a/src/xdocs/faq.xml +++ /dev/null @@ -1,1908 +0,0 @@ - - - - - - - - - - - Ceki Gülcü - - Frequently Asked Questions about log4j - - - - - - - - - -
    - -

    Frequently Asked Questions about log4j

    - -

    Ceki Gülcü, Paul Smith, Chris Taylor
    - - May 2002, last updated on September 15th, 2004

    - -
    - - - - - - Generalities - - - - - -

    This section contains general questions about log4j.

    - -
    - - - - - - What is log4j? - - - -

    log4j is a tool to help the programmer output log statements to a - - variety of output targets. - -

    - - - -

    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 shipped code without - - incurring a high performance cost. It follows that the speed - - of logging (or rather not logging) is capital. - -

    - - - -

    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 hierarchical loggers. Using loggers it is - - possible to selectively control which log statements are output at - - arbitrary granularity. - -

    - - - -

    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. - -

    - -
    - - - -
    - - - - - - - - Is log4j a reliable logging system? - - - -

    No. log4j is not reliable. It is a best-effort - - fail-stop logging system. - -

    - - - -

    By fail-stop, we mean that log4j will not throw unexpected - - exceptions at run-time potentially causing your application to - - crash. If for any reason, log4j throws an uncaught exception, - - please send an email to the log4j-user@logging.apache.org - - mailing list. Uncaught exceptions are handled as serious bugs - - requiring immediate attention. - -

    - - - -

    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. - -

    - -
    - -
    - - - - - - What are the prerequisites for log4j? - - - -
      - -
    • 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. - -

    • - - - -
    • 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. - -

      - -

      The DOMConfigurator.configure(String filename) method and its - - variants require a JAXP compatible XML parser, for example Xerces or Sun's - - parser. Compiling the DOMConfigurator requires the presence of a - - JAXP parser in the classpath. - -

      - -
    • - - - -
    • The org.apache.log4j.net.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. - -

    • - - - -
    • The org.apache.log4j.net.JMSAppender - - requires the presence of the JMS API as well as JNDI. - -

    • - - - -
    • log4j test code relies on the JUnit testing framework. - -

    • - -
    - -
    - -
    - - - - - - What are the features of log4j? - - - -
      - - - -
    • log4j is optimized for speed.

    • - - - -
    • log4j is based on a named logger hierarchy.

    • - - - -
    • 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. - -

    • - - - -
    • log4j is thread-safe.

    • - - - -
    • log4j is not restricted to a predefined set of - - facilities.

    • - - - -
    • Logging behavior can be set at runtime using a - - configuration file. Configuration files can be property - - files or in XML format.

    • - - - -
    • log4j is designed to handle Java Exceptions from the - - start.

    • - - - -
    • log4j can direct its output to a file, the console, - - an java.io.OutputStream, - - java.io.Writer, 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.

    • - - - -
    • log4j uses 6 levels, namely TRACE, DEBUG, INFO, WARN, - - ERROR and FATAL.

    • - - - -
    • The format of the log output can be easily changed by - - extending the Layout - - class.

    • - - - -
    • The target of the log output as well as the writing - - strategy can be altered by implementations of the - - Appender interface.

    • - - - -
    • log4j supports multiple output appenders per logger. - -

    • - - - -
    • log4j supports internationalization.

    • - -
    - -
    - -
    - - - - - - Is there example code for using log4j? - - - -

    See the examples/ directory.

    - -
    - -
    - - - - - - What documentation should I read to learn more about - - log4j? - - - -

    Make sure to read the short - - manual. It is also recommended to you read The complete - - log4j manual which is much more detailed and up to - - date. Both documents were written by Ceki Gülcü. - -

    - -
    - -
    - - - - - - Is log4j thread-safe? - - - -

    Yes, log4j is thread-safe. Log4j components are designed to - - be used in heavily multithreaded systems.

    - -
    - -
    - - - - - - What does log output look like? - - - - - -

    The log output can be customized in many ways. Moreover, - - one can completely override the output format by implementing - - one's own Layout. - -

    - - - -

    Here is an example output using PatternLayout with - - the conversion pattern "%r [%t] %-5p %c{2} %x - %m%n" - -

    - - - -
    -
    -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.
    -
    -276 [main] DEBUG SortAlgo.SWAP i=1 j=0 - Swapping intArray[0] = 1 and intArray[1] = 0
    -
    -290 [main] DEBUG SortAlgo.OUTER i=0 - Outer loop.
    -
    -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.
    -
    -	
    - - - -

    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 nested diagnostic - - context (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. - -

    - -
    - -
    - - - - - - - - - - Why should I use log4j when JDK 1.4 already ships with a - - logging API? - - - - - -

    - - 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. - -

    - - - -

    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. - -

    - -
    - -
    - - - -
    - - - - - - Using log4j - - - - - -

    This section contains answers to questions encountered while - - using log4j.

    - -
    - - - - - - What are <em>Loggers</em>? - - - -

    Lggers lie at the heart of log4j. Loggers define a hierarchy and give - - the programmer run-time control on which statements are - - printed or not. - -

    - - - -

    Loggers are assigned levels. A log statement is printed - - depending on its level and its logger. - -

    - - - -

    Make sure to read the log4j manual - - for more information. - -

    - -
    - -
    - - - - - - How can I change log behavior at runtime? - - - -

    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. - -

    - - - -

    The PropertyConfigurator defines a particular format - - of a configuration file. See also the examples/Sort.java - - example and associated configuration files. - -

    - - - -

    Configuration files can be specified in XML. See - - log4j.dtd and - - org.log4j.xml.DOMConfigurator for more details. - -

    - - - -

    See the various Layout and Appender components for specific - - configuration options. - -

    - - - -

    In addition to configuration files, the user may disable all - - messages belonging to a set of levels. See next item. - -

    - -
    - -
    - - - - - - What is the fastest way of (not) logging? - - - - - -

    For some logger l, writing, - -

    - - - -
    -
    - l.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
    -
    -	
    - - - -

    incurs the cost of constructing the message parameter, that is - - converting both integer i and entry[i] to a - - String, and concatenating intermediate strings. This, regardless of - - whether the message will be logged or not. - -

    - - - -

    If you are worried about speed, then write

    - -
    -
    -   if(l.isDebugEnabled()) {
    -
    -     l.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
    -
    -   }
    -
    -	
    - - - -

    This way you will not incur the cost of parameter - - construction if debugging is disabled for logger - - l. 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 - - debugEnabled and once in debug. - - This is an insignificant overhead since evaluating a logger - - takes less than 1% of the time it takes to actually log a - - statement. - -

    - - - -

    Better alternative based on message patterns

    - -

    As of log4j version 1.3, there exists a significantly more - - convenient alternative based on message patterns. Assuming - - entry is an object, you can write: - -

    - - - -

    - - l.debug("The new entry is {}.", entry); - -

    - - - -

    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 - - entry. In other words, the paramerized form does - - not incur the cost of parameter construction in case the log - - statement is disabled. - -

    - - - -

    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 disabled logging - - statement. - -

    - - - -

    - - l.debug("The new entry is "+entry+".");
    - - l.debug("The new entry is {}.", entry); - -

    - - - -

    A two argument variant is also availalble. For example, you - - can write: - -

    - -

    - - l.debug("The new entry is {}. It replaces {}.", entry, oldEntry); - -

    - - - - - - - -
    - -
    - - - - - - Are there any suggested ways for naming loggers? - - - - - - - -

    Yes, there are.

    - - - -

    You can name loggers by locality. 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: - -

    - - - -
      - -
    • It is very simple to implement.
    • - - - -
    • It is very simple to explain to new developers.
    • - - - -
    • It automatically mirrors your application's own modular design. - -
    • - -
    • It can be further refined at will.
    • - - - -
    • Printing the logger automatically gives information on the locality - - of the log statement.
    • - -
    - - - -

    However, this is not the only way for naming loggers. A - - common alternative is to name loggers by functional - - areas. For example, the "database" logger, "RMI" - - logger, "security" logger, or the "XML" logger. - -

    - - - -

    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". - -

    - - - -

    You are totally free in choosing the names of your - - loggers. The log4j package merely allows you to manage your - - names in a hierarchy. However, it is your responsibility to define - - this hierarchy. - -

    - - - -

    Note by naming loggers by locality one tends to name things by - - functionality, since in most cases the locality relates closely to - - functionality. - -

    - - - -
    - -
    - - - - - - - - How do I get the fully-qualified name of a class in a static block? - - - -

    You can easily retrieve the fully-qualified name of a class in a - - static block for class X, with the statement - - X.class.getName(). Note that X is the class - - name and not an instance. The X.class statement does - - not create a new instance of class X. - -

    - - - -

    Here is the suggested usage template:

    - - - -
    -
    -package a.b.c;
    -
    -
    -
    -public class Foo {
    -
    -  final static Logger logger = Logger.getLogger(Foo.class);
    -
    -  ... other code
    -
    -
    -
    -}
    -
    -	
    - -
    - -
    - - - - - - Can the log output format be customized? - - - -

    Yes, you can extend the Layout class to create - - you own customized log format. Appenders can be parameterized - - to use the layout of your choice. - -

    - -
    - -
    - - - - - - - - - - What are the configurable options for <code>FooBarAppender</code>? - - - -

    Log4j uses JavaBeans style configuration.

    - - - -

    Thus, any setter method in FooBarAppender - - corresponds to a configurable option. For example, in RollingFileAppender - - the setMaxBackupIndex(int - - maxBackups) method corresponds to the - - maxBackupIndex option. The first letter of the - - option can be upper case, i.e. MaxBackupIndex - - and maxBackupIndex are equivalent but not - - MAXBACKUPIndex nor mAXBackupIndex. - -

    - - - -

    Layouts options are also defined by their setter methods. The same goes - - for most other log4j components. - -

    - -
    - -
    - - - - - - - - What is the recommended way of migrating from - - java.util.logging to log4j? - - - - - -

    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. - -

    - - - -

    If you're on a Win32 platform, we recommend Textpad. 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! :) - -

    - -
    - -
    - - - - - - - - Is it possible to direct log output to - - different appenders by level? - - - -

    Yes it is. Setting the Threshold option of any appender - - extending AppenderSkeleton, - - (most log4j appenders extend AppenderSkeleton) to filter out all log - - events with lower level than the value of the threshold - - option. - -

    - - - -

    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. - -

    - - - -

    This policy usually best encapsulates what the user - - actually wants to do, as opposed to her mind-projected - - solution. - -

    - -

    See examples/sort4.lcf for an example threshold - - configuration.

    - - - -

    If you must filter events by exact level match, then you can - - attach a LevelMatchFilter - - to any appender to filter out logging events by exact level match. - -

    - - - -
    - -
    - - - - - - - - What does the Windows NT Event Viewer complain about - - missing descriptions for my event messages when I use the - - <code>NTEventLogAppender</code>? - - - - - -

    The NT Event Viewer relies on message resource 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. - -

    - -
    - -
    - - - - - - - - Why can't I map my logger names to the loggers that - - appear in the NT Event Log when I use the - - NTEventLogAppender? - - - - - -

    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... - -

    - -
    - -
    - - - - - - - - Are there suggested approaches for logging in JSP pages? - - - -

    - - 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 <% ... %> statements - - as indicated in the Short Manual and the rest of the documentation. - -

    - -

    - - However, if your design calls for a minimum amount of Java in your JSP - - pages, consider using the - - Log Taglib - - from the Jakarta Taglibs project. It provides logging JSP tags that invoke - - log4j. - -

    - -
    - -
    - - - -
    - - - - - - Advanced questions - - - - - -

    This section contains answers to more advanced questions about log4j.

    - -
    - - - - - - Can the outputs of multiple client request go to - - different log files? - - - - - -

    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. - -

    - - - -

    It is simpler to use a nested diagnostic context - - (NDC). Typically, one would NDC.push() 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. - -

    - - - -

    See the NDC and the PatternLayout - - classes for more information. The NumberCruncher - - example shows how the NDC can be used to distinguish the log - - output from multiple clients even if they share the same log - - file. - -

    - - - -

    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. - -

    - - - -
    - -
    - - - - - - - - Logger instances seem to be create only. Why isn't - - there a method to remove logger instances? - - - -

    It is quite nontrivial to define the semantics of a - - "removed" logger escecially if it is still referenced by the - - user. Future releases may include a remove method in - - the Logger class.

    - -
    - -
    - - - - - - How do I get multiple process to log to the same file? - - - -

    You may have each process log to a - - SocketAppender. - - The receiving - - SocketServer - - (or - - SimpleSocketServer) - - can receive all the events and send them to a single - - log file. - -

    - -
    - -
    - - - - - - How about the timesamps of events generated by multiple - - processes across multiple hosts (possibly across multiple - - timezones)? - - - - - - - - - -

    The timestamp is created when the logging event is created. - - That is so say, when the debug, - - info, warn, error or - - fatal method is invoked. Thus, the timestamp is - - unaffected by the time at which event arrive at a remote - - socket server. - -

    - - - -

    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. - -

    - -
    - -
    - - - - - - Why can't log4j find my properties file in a J2EE or WAR - - application? - - - - - - - -

    The short answer: the log4j classes and the properties file - - are not within the scope of the same classloader. - -

    - - - -

    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. - -

    - - - -

    Log4j only uses the default Class.forName() - - mechanism for loading classes. Resources are handled - - similarly. See the documentation for - - java.lang.ClassLoader for more details. - -

    - - - -

    So, if you're having problems, try loading the class or - - resource yourself. If you can't find it, neither will - - log4j. ;) - -

    - - - -
    - -
    - - - - - - Is there a way to get log4j to automatically reload a - - configuration file if it changes? - - - -

    Yes. Both the DOMConfigurator and the PropertyConfigurator support - - automatic reloading through the configureAndWatch method. - - See the API documentation for more details. - -

    - - - - - -

    Because the configureAndWatch launches a - - separate wathdog thread, and because there is no way to stop - - this thread in log4j 1.2, the configureAndWatch - - method is unsafe for use in J2EE envrironments where - - applications are recycled. - -

    - - - -
    - -
    - -
    - - - - - - - - Contributing to the project - - - -

    This section includes questions about contributing to the - - project

    - -
    - - - - - - Why should I donate my extensions to log4j back to the - - project? - - - - - - - -

    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. You are free to do - - whatever you wish with your proprietary log4j extensions. - - In particular, you may choose to never release your extensions - - to the wider public. - -

    - - - -

    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 n, then when log4j - - release version n+1 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. - -

    - - - -

    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. - -

    - -
    - -
    - - - - What should I keep in mind when contributing code? - - - -
      - - - -
    1. - -

      Write a test case for your contribution.

      - - - -

      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. - -

      - -
    2. - - - - - -
    3. - -

      Stick to the existing indentation style even if you hate it.

      - - - -

      Alternating between indentation styles makes it hard to - - understand the source code. Make it a little harder on - - yourself but easier on others. - -

      - - - -

      Log4j has adopted a rather conservative approach by - - following the Code Conventions - - for the JavaTM Programming Language. We use 2 (two) - - spaces for indentation and no tabs. - -

      - -
    4. - - - -
    5. - -

      Please do not both modify the code and change the - - indentation in a single commit.

      - - - -

      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. - -

      - - - -

      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. - -

      - - - -
    6. - -
    7. - -

      Make every effort to stick to the JDK 1.1 API.

      - - - -

      One of the important advantages of log4j is its - - compatibility with JDK 1.1.x. - -

      - -
    8. - - - -
    9. - -

      Always keep it simple, small and fast when - - possible.

      - - - -

      It's all about the application not about logging.

      - -
    10. - - - -
    11. - -

      Identify yourself as a contributor at the top of the - - relevant file. - -

      - -
    12. - -
    13. - -

      Take responsibility for your code.

      - - - -

      Authoring software is very much like running a marathon. It - - takes time and endurance. - -

      - -
    14. - -
    15. - -

      Did we mention sticking with the indentation style?

      - -
    16. - -
    17. Did we mention writing test cases?

      - -
    18. - - - -
    - -
    - -
    - - - - - - How can I contribute a new question/answer to this - - document? - - - -

    Log4j uses velocity-anakia - - to generate its web-site, including this FAQ. We have devised - - special macros to help us automatically generate labeled - - question/answer pairs. - -

    - - - -

    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. - -

    - - - -

    If you are a committer, then you must edit the - - /src/xdocs/faq.xml file. The format of the file - - should be self-evident. After you have made your changes, run - - the command - -

    - -
    ant site
    - - - -

    After the appropriate transformation, your changes should - - appear in the file /docs/faq.html. - -

    - -
    - -
    - -
    - - - -
    - - - - - - - - - diff --git a/src/xdocs/history.xml b/src/xdocs/history.xml deleted file mode 100644 index fbe5480d4b..0000000000 --- a/src/xdocs/history.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - Ceki Gülcü - Project history - - - - -
    - -

    The project history gives a - brief summary of changes and additions. Users frequently - report bugs that are solved in newer versions of log4j. Please - have a look at the history file before asking for help. -

    - -

    The project's official URL is http://logging.apache.org/log4j. -

    - -

    Many thanks to all the log4j users who keep sending us input - and sometimes even praise for our collective effort. The first - ancestor of log4j was written for the E.U. sponsored SEMPER project. N. Asokan, - Ceki Gülcü and Michael Steiner came up with the idea - of hierarchical loggers back in 1996. Their idea is still at the - heart of log4j. The package was considerably improved over the - years at the IBM Zurich - Research Laboratory. However, log4j is no longer associated - nor supported by IBM. -

    - -

    Special thanks to M. Niksch from ZRL for his assistance on - many large and small matters. The Apache members, Pier - Fumagalli and Sam Ruby in particular, have been extremely - helpful in easing the move to Apache. -

    - -

    The log4j logo was designed and kindly donated by Cyberlab SA of Switzerland. -

    - -
    - -
    diff --git a/src/xdocs/index.xml b/src/xdocs/index.xml deleted file mode 100644 index c6555d4fc7..0000000000 --- a/src/xdocs/index.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - Ceki Gülcü - Introduction - - - - - - - -
    - -

    Inserting log statements into your code is a low-tech method - for debugging it. It may also be the only way because - debuggers are not always available or applicable. This is - often the case for distributed applications.

    - -

    On the other hand, some people argue that log statements - pollute source code and decrease legibility. (We believe that - the contrary is true). In the Java language where a - preprocessor is not available, log statements increase the - size of the code and reduce its speed, even when logging is - turned off. Given that a reasonably sized application may - contain thousands of log statements, speed is of particular - importance.

    - - -

    With log4j it is possible to enable logging at runtime - without modifying the application binary. The log4j package is - designed so that these statements can remain in shipped code - without incurring a heavy performance cost. Logging behavior - can be controlled by editing a configuration file, without - touching the application binary.

    - -

    Logging equips the developer with detailed context for - application failures. On the other hand, testing provides - quality assurance and confidence in the application. Logging - and testing should not be confused. They are - complementary. When logging is wisely used, it can prove to be - an essential tool.

    - -

    One of the distinctive features of log4j is the notion of - inheritance in loggers. Using a logger - hierarchy it is possible to control which log - statements are output at arbitrarily fine granularity but also - great ease. This helps reduce the volume of logged output and - minimize the cost of logging.

    - -

    The target of the log output can be a file, an - OutputStream, a java.io.Writer, a - remote log4j server, a remote Unix Syslog daemon, or many other output targets.

    - -

    On an AMD Duron clocked at 800Mhz running JDK 1.3.1, it costs - about 5 nanoseconds to determine if a logging statement should - be logged or not. Actual logging is also quite fast, ranging - from 21 microseconds using the SimpleLayout, 37 - microseconds using the TTCCLayout. The performance of the - PatternLayout is almost as good as the dedicated layouts, - except that it is much more flexible.

    - -

    The package is being constantly improved thanks to input from - users and code contributed by authors in the community. -

    - -
    - -
    - diff --git a/src/xdocs/install-chainsaw.xml b/src/xdocs/install-chainsaw.xml deleted file mode 100644 index 59885e15d7..0000000000 --- a/src/xdocs/install-chainsaw.xml +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - -============================================================ -CHAINSAW v2 installer -============================================================ -This Ant build script will perform the following: - * Download the logging-chainsaw and logging-log4j modules from the Apache CVS - * Dowload the latest binary version of the Jakarta ORO project from www.ibiblio.org - -It will create the following artifacts in the current directory (whereever this Ant script is) - * a logging-chainsaw directory, containing the chainsaw source tree - * a logging-log4j directory, containing the log4j source tree - * a jakarta-oro-2.0.8.zip file - * a jakarta-oro-2.0.8 directory containing the unpacked ORO jar from the aforementioned zip file - - - - - - Installation aborted by user. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Download of files completed successfully. - -You should now be able to do the following to run Chainsaw v2 - - 1. execute logging-log4j's jar target - * cd logging-log4j - * copy sample.build.properties to build.properties - * modify build.properties file to specify servlet path at a minimum - * run the 'jar' ant target: ant jar - - 2. execute logging-chainsaw's ant target - * cd logging-chainsaw - * mkdir lib - * copy all jars in the logging-log4j directory to lib - * copy other dependencies (vfs, commons-logging) (but not ORO) to lib - * ant chainsaw - -GOOD LUCK! - - - diff --git a/src/xdocs/plan.xml b/src/xdocs/plan.xml deleted file mode 100644 index 1c10af3a34..0000000000 --- a/src/xdocs/plan.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - Ceki Gülcü - Mark Womack - Curt Arnold - Release roadmap for log4j - - - - -
    - -

    This page documents that roadmap and gives you an idea of what - to expect from future versions and timeframes for release. -

    - -

    Our users keep inventing better ways and adding new - requirements. The downside is that our todo list keeps - growing. The upside is that there is plenty of work to go - around. If you are interested in participating, send an email - on the log4j-dev@ mailing list stating your interest. You'll - be promptly enrolled. We're always looking for help! Don't be - put off if in the "Volunteer" column already has a person - listed. Programming is fun, especially if it is done in a - team. -

    - -
    - -
    -

    Expected timeframe: As needed

    - -

    log4j 1.2.14 was released in September 2006. log4j 1.2 is continuing to be maintained - in response to reported, but no active development is anticipated in the near future. Backporting - the org.apache.log4j.rolling package from log4j 1.3 might be desirable since usage problems - with the original org.apache.log4j.RollingFileAppender and org.apache.log4j.DailyRollingFileAppender - are commonly reported.

    -
    - -
    -

    Expected timeframe: indeterminate

    - -

    Compatibility with earlier releases (as implied by a minor verion number change) was not enforced during the - development process and much of the recent effort has been to restore compatibility. However, it does not - seem likely that log4j 1.3 will ever been sufficiently compatible with log4j 1.2 - to recommend it as a general replacement for log4j 1.2. Additional alpha releases are expected, - however it is possible that the development focus may shift to log4j 2.0.

    - -
    - -
    -

    Expected timeframe: indeterminate

    - -

    log4j 2.0 is still conceptual but would be designed for Java 5 and later, - would use be designed for fine-grain concurrency to maximize performance on - multi-processor systems, would minimize exposure of implementation details and - adhere to current Java coding practices. The design of log4j 2.0 may attempt to - support javax.util.logging by allowing, for example, a log4j 2.0 Appender to serve - as a javax.util.logging.Handler. log4j 2.0 would likely be modularized, possibly using - OSGi and would include a facade that emulates the log4j 1.3 API but would not be compatible - with user written appenders and other components.

    -
    - - - -
    diff --git a/src/xdocs/stylesheets/compatibility.xslt b/src/xdocs/stylesheets/compatibility.xslt deleted file mode 100644 index 3f1a9e761f..0000000000 --- a/src/xdocs/stylesheets/compatibility.xslt +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - Apache log4j compatibility report - - -

    Apache log4j compatibility report

    - - - -
    - - - - -
    -
    - - -
    - - o.a.l. - - - - . - - - - -
    - - - - - - ##

    - * Relies on the fact that the matchingKeywords list is in the same - * order as the groups in the regular expression - * - * @param result - * @return map - */ - private Map processEvent(MatchResult result) { - Map map = new HashMap(); - //group zero is the entire match - process all other groups - for (int i = 1; i < result.groups(); i++) { - map.put(matchingKeywords.get(i - 1), result.group(i)); - } - return map; - } - - /** - * Helper method that will convert timestamp format to a pattern - * - * - * @return string - */ - private String convertTimestamp() { - return util.substitute("s/("+VALID_DATEFORMAT_CHAR_PATTERN+")+/\\\\w+/g", timestampFormat); - } - - protected void setHost(String host) { - this.host = host; - } - - protected void setPath(String path) { - this.path = path; - } - - /** - * Build the regular expression needed to parse log entries - * - */ - protected void initialize() { - if (host == null && path == null) { - try { - URL url = new URL(fileURL); - host = url.getHost(); - path = url.getPath(); - } catch (MalformedURLException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - } - if (host == null || host.trim().equals("")) { - host = DEFAULT_HOST; - } - if (path == null || path.trim().equals("")) { - path = fileURL; - } - - util = new Perl5Util(); - exceptionCompiler = new Perl5Compiler(); - exceptionMatcher = new Perl5Matcher(); - - currentMap = new HashMap(); - additionalLines = new ArrayList(); - matchingKeywords = new ArrayList(); - - if (timestampFormat != null) { - dateFormat = new SimpleDateFormat(timestampFormat); - timestampPatternText = convertTimestamp(); - } - - try { - if (filterExpression != null) { - expressionRule = ExpressionRule.getRule(filterExpression); - } - } catch (Exception e) { - getLogger().warn("Invalid filter expression: " + filterExpression, e); - } - - Map keywordMap = new TreeMap(); - - String newPattern = logFormat; - - /* - * examine pattern, adding properties to an index-based map where the key is the - * numeric offset from the start of the pattern so that order can be preserved - * - * Replaces PROP(X) definitions in the pattern with the short version X, so - * that the name can be used as the event property later - */ - int index = 0; - int currentPosition = 0; - String current = newPattern; - while (index > -1) { - index = current.indexOf(PROP_START); - currentPosition = currentPosition + index; - if (index > -1) { - String currentProp = current.substring(current.indexOf(PROP_START)); - String prop = currentProp.substring(0, - currentProp.indexOf(PROP_END) + 1); - current = current.substring(current.indexOf(currentProp) + 1); - String shortProp = prop.substring(PROP_START.length(), - prop.length() - 1); - keywordMap.put(new Integer(currentPosition), shortProp); - newPattern = replace(prop, shortProp, newPattern); - } - } - - newPattern = replaceMetaChars(newPattern); - - //compress one or more spaces in the pattern into the [ ]+ regexp - //(supports padding of level in log files) - newPattern = util.substitute("s/" + MULTIPLE_SPACES_REGEXP +"/" + MULTIPLE_SPACES_REGEXP + "/g", newPattern); - newPattern = replace(PATTERN_WILDCARD, REGEXP_DEFAULT_WILDCARD, newPattern); - - /* - * we're using a treemap, so the index will be used as the key to ensure - * keywords are ordered correctly - * - * examine pattern, adding keywords to an index-based map patterns can - * contain only one of these per entry...properties are the only 'keyword' - * that can occur multiple times in an entry - */ - Iterator iter = keywords.iterator(); - while (iter.hasNext()) { - String keyword = (String) iter.next(); - int index2 = newPattern.indexOf(keyword); - if (index2 > -1) { - keywordMap.put(new Integer(index2), keyword); - } - } - - //keywordMap should be ordered by index..add all values to a list - matchingKeywords.addAll(keywordMap.values()); - - /* - * iterate over the keywords found in the pattern and replace with regexp - * group - */ - String currentPattern = newPattern; - for (int i = 0;inew. + * @deprecated Use getNullAppender instead. getInstance should have been static. * */ - static public NullAppender getInstance() { + public NullAppender getInstance() { return instance; } + /** + * Whenever you can, use this method to retreive an instance instead + * of instantiating a new one with new. + * */ + public static NullAppender getNullAppender() { + return instance; + } + public void close() { } @@ -56,13 +69,11 @@ public void doAppend(LoggingEvent event) { * */ protected void append(LoggingEvent event) { } - /** - * Gets whether appender requires a layout. - * @return false - */ + + /** + * NullAppenders do not need a layout. + * */ public boolean requiresLayout() { - return false; + return false; } - - } diff --git a/src/main/java/org/apache/log4j/varia/ReloadingPropertyConfigurator.java b/src/main/java/org/apache/log4j/varia/ReloadingPropertyConfigurator.java new file mode 100644 index 0000000000..ac7657731f --- /dev/null +++ b/src/main/java/org/apache/log4j/varia/ReloadingPropertyConfigurator.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.varia; + +import java.io.InputStream; +import java.net.URL; + +import org.apache.log4j.PropertyConfigurator; +import org.apache.log4j.spi.Configurator; +import org.apache.log4j.spi.LoggerRepository; + +public class ReloadingPropertyConfigurator implements Configurator { + + PropertyConfigurator delegate = new PropertyConfigurator(); + + public ReloadingPropertyConfigurator() { + } + + /** + * @since 1.2.17 + */ + public void doConfigure(InputStream inputStream, LoggerRepository repository) { + } + + public void doConfigure(URL url, LoggerRepository repository) { + } + +} diff --git a/src/main/java/org/apache/log4j/varia/Roller.java b/src/main/java/org/apache/log4j/varia/Roller.java index f4abd0ec6a..4fdf896de5 100644 --- a/src/main/java/org/apache/log4j/varia/Roller.java +++ b/src/main/java/org/apache/log4j/varia/Roller.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -35,19 +35,17 @@ @author Ceki Gülcü - @since version 0.9.0 - @deprecated 1.3 - */ + @since version 0.9.0 */ public class Roller { - private static final Logger logger = Logger.getLogger(Roller.class); + static Logger cat = Logger.getLogger(Roller.class); - private static String host; - private static int port; + static String host; + static int port; // Static class. - private Roller() { + Roller() { } /** @@ -58,28 +56,29 @@ private Roller() { */ public static - void main(final String argv[]) { + void main(String argv[]) { BasicConfigurator.configure(); - if(argv.length == 2) - init(argv[0], argv[1]); - else - usage("Wrong number of arguments."); + if(argv.length == 2) { + init(argv[0], argv[1]); + } else { + usage("Wrong number of arguments."); + } roll(); } - private static - void usage(final String msg) { + static + void usage(String msg) { System.err.println(msg); System.err.println( "Usage: java " + Roller.class.getName() + "host_name port_number"); System.exit(1); } - private static - void init(final String hostArg, final String portArg) { + static + void init(String hostArg, String portArg) { host = hostArg; try { port = Integer.parseInt(portArg); @@ -89,11 +88,6 @@ void init(final String hostArg, final String portArg) { } } - /** - * Sends a roll request on the specified port. - * - * @deprecated Deprecated since ExternallyRolledFileAppender is deprecated - */ static void roll() { try { @@ -103,13 +97,13 @@ void roll() { dos.writeUTF(ExternallyRolledFileAppender.ROLL_OVER); String rc = dis.readUTF(); if(ExternallyRolledFileAppender.OK.equals(rc)) { - logger.info("Roll over signal acknowledged by remote appender."); + cat.info("Roll over signal acknowledged by remote appender."); } else { - logger.warn("Unexpected return code "+rc+" from remote entity."); - System.exit(2); + cat.warn("Unexpected return code "+rc+" from remote entity."); + System.exit(2); } } catch(IOException e) { - logger.error("Could not send roll signal on host "+host+" port "+port+" .", + cat.error("Could not send roll signal on host "+host+" port "+port+" .", e); System.exit(2); } diff --git a/src/main/java/org/apache/log4j/varia/SoundAppender.java b/src/main/java/org/apache/log4j/varia/SoundAppender.java deleted file mode 100644 index 681278643a..0000000000 --- a/src/main/java/org/apache/log4j/varia/SoundAppender.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.varia; - -import java.applet.Applet; -import java.applet.AudioClip; -import java.net.MalformedURLException; -import java.net.URL; - -import org.apache.log4j.AppenderSkeleton; -import org.apache.log4j.spi.LoggingEvent; - -/** - * Plays a sound clip created using Applet.newAudioClip when an event is received. - * - * If the audio format is not supported, a message stating the SoundAppender could - * not be initialized is logged. - * - * Use a filter in combination with this appender to control when the appender is - * triggered. - * - * For example, in the appender definition, include a LevelMatchFilter configured - * to accept WARN or greater, followed by a DenyAllFilter. - * - * @author Scott Deboy - * - */ -public final class SoundAppender extends AppenderSkeleton { - - private AudioClip clip; - private String audioURL; - - public SoundAppender() { - super(true); - } - - /** - * Attempt to initialize the appender by creating a reference to an AudioClip. - * - * Will log a message if format is not supported, file not found, etc. - * - */ - public void activateOptions() { - /* - * AudioSystem.getAudioInputStream requires jdk 1.3, - * so we use applet.newaudioclip instead - * - */ - try { - clip = Applet.newAudioClip(new URL(audioURL)); - } catch (MalformedURLException mue) {getLogger().error("unable to initialize SoundAppender", mue);} - if (clip == null) { - getLogger().error("Unable to initialize SoundAppender"); - } - } - - /** - * Accessor - * - * @return audio file - */ - public final String getAudioURL() { - return audioURL; - } - - /** - * Mutator - common format for a file-based url: - * file:///c:/path/someaudioclip.wav - * - * @param audioURL - */ - public void setAudioURL(String audioURL) { - this.audioURL = audioURL; - } - - /** - * Play the sound if an event is being processed - */ - protected void append(LoggingEvent event) { - if (clip != null) { - clip.play(); - } - } - - public void close() { - //nothing to do - } - - /** - * Gets whether appender requires a layout. - * @return false - */ - public boolean requiresLayout() { - return false; - } - -} diff --git a/src/main/java/org/apache/log4j/varia/StringMatchFilter.java b/src/main/java/org/apache/log4j/varia/StringMatchFilter.java index 93f8cf4011..9d161c6e57 100644 --- a/src/main/java/org/apache/log4j/varia/StringMatchFilter.java +++ b/src/main/java/org/apache/log4j/varia/StringMatchFilter.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,53 +17,106 @@ package org.apache.log4j.varia; +import org.apache.log4j.spi.Filter; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.helpers.OptionConverter; /** - * near term. + */ + public static final String STRING_TO_MATCH_OPTION = "StringToMatch"; - /** - @deprecated Options are now handled using the JavaBeans paradigm. - This constant is not longer needed and will be removed in the - near term. - */ - public static final String ACCEPT_ON_MATCH_OPTION = "AcceptOnMatch"; + /** + @deprecated Options are now handled using the JavaBeans paradigm. + This constant is not longer needed and will be removed in the + near term. + */ + public static final String ACCEPT_ON_MATCH_OPTION = "AcceptOnMatch"; + + boolean acceptOnMatch = true; + String stringToMatch; + + /** + @deprecated We now use JavaBeans introspection to configure + components. Options strings are no longer needed. + */ + public + String[] getOptionStrings() { + return new String[] {STRING_TO_MATCH_OPTION, ACCEPT_ON_MATCH_OPTION}; + } - /** - @deprecated We now use JavaBeans introspection to configure - components. Options strings are no longer needed. - */ - public - String[] getOptionStrings() { - return new String[] {STRING_TO_MATCH_OPTION, ACCEPT_ON_MATCH_OPTION}; + /** + @deprecated Use the setter method for the option directly instead + of the generic setOption method. + */ + public + void setOption(String key, String value) { + + if(key.equalsIgnoreCase(STRING_TO_MATCH_OPTION)) { + stringToMatch = value; + } else if (key.equalsIgnoreCase(ACCEPT_ON_MATCH_OPTION)) { + acceptOnMatch = OptionConverter.toBoolean(value, acceptOnMatch); } + } + + public + void setStringToMatch(String s) { + stringToMatch = s; + } + + public + String getStringToMatch() { + return stringToMatch; + } + + public + void setAcceptOnMatch(boolean acceptOnMatch) { + this.acceptOnMatch = acceptOnMatch; + } + + public + boolean getAcceptOnMatch() { + return acceptOnMatch; + } - /** - @deprecated Use the setter method for the option directly instead - of the generic setOption method. - */ - public - void setOption(String key, String value) { + /** + Returns {@link Filter#NEUTRAL} is there is no string match. + */ + public + int decide(LoggingEvent event) { + String msg = event.getRenderedMessage(); - if(key.equalsIgnoreCase(STRING_TO_MATCH_OPTION)) { - this.setStringToMatch(value); - } else if (key.equalsIgnoreCase(ACCEPT_ON_MATCH_OPTION)) { - this.setAcceptOnMatch(Boolean.valueOf(value).booleanValue()); - } + if(msg == null || stringToMatch == null) { + return Filter.NEUTRAL; } + - + if( msg.indexOf(stringToMatch) == -1 ) { + return Filter.NEUTRAL; + } else { // we've got a match + if(acceptOnMatch) { + return Filter.ACCEPT; + } else { + return Filter.DENY; + } + } + } } diff --git a/src/main/java/org/apache/log4j/varia/package.html b/src/main/java/org/apache/log4j/varia/package.html index 8c9ed2cd39..3495db241d 100644 --- a/src/main/java/org/apache/log4j/varia/package.html +++ b/src/main/java/org/apache/log4j/varia/package.html @@ -1,4 +1,21 @@ + diff --git a/src/main/java/org/apache/log4j/watchdog/FileWatchdog.java b/src/main/java/org/apache/log4j/watchdog/FileWatchdog.java deleted file mode 100644 index 91e68d794e..0000000000 --- a/src/main/java/org/apache/log4j/watchdog/FileWatchdog.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright 1999,2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.watchdog; - -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggerRepositoryEx; -import org.apache.log4j.scheduler.Job; - -import java.io.*; - -/** - * Implements a watchdog to watch a file. When the file changes, determined by - * a change in the file's modification date, the contents of the file are use to - * reconfigure the log4j environment. - */ -public class FileWatchdog extends WatchdogSkeleton implements Job { - - public static final long DEFAULT_INTERVAL = 60000; - - private String filePath; - private long interval = DEFAULT_INTERVAL; - private boolean initialConfigure = false; - - /** The file being watched. */ - private File watchedFile; - private long lastModTime = -1; - - /** - * Sets the path of the file to use and watch for configuration changes. - * - * @param filePath - */ - public void setFile(String filePath) { - this.filePath = filePath; - } - - /** - * Returns the path of the file being watched for confirguration changes. - * - * @return the path of the file being watched - */ - public String getFile() { - return filePath; - } - - /** - * Sets the interval of time between checks for file modifications. - * - * @param interval - */ - public void setInterval(long interval) { - this.interval = interval; - } - - /** - * Returns the interval of time between checks for file modifications. - * - * @return interval of time - */ - public long getInterval() { - return interval; - } - - /** - * Set to true if watchdog should configure with file before starting watch - * in activateOptions. - * - * @param initialConfigure - */ - public void setInitialConfigure(boolean initialConfigure) { - this.initialConfigure = initialConfigure; - } - - /** - * Returns true if watchdog will configure before starting watch in - * activateOptions. - * - * @return - */ - public boolean getInitialConfigure() { - return initialConfigure; - } - - /** - * Returns the last modification time of the watched file. - * - * @return - */ - public long getLastModTime() { - return lastModTime; - } - - /** - * Sets up the reference to the file being watched, then calls the version - * in the super class. - */ - public void activateOptions() { - getLogger().debug("activateOptions called for watchdog " + this.getName()); - - if (filePath == null) { - getLogger().error("watchdog \"{}\" not configured with path to watch", - this.getName()); - return; - } - - watchedFile = new File(filePath); - - // do an initial configure or record the current mod time - if (initialConfigure) { - execute(); - } else if (watchedFile.exists()) { - lastModTime = watchedFile.lastModified(); - } - - LoggerRepository repo = getLoggerRepository(); - if (repo instanceof LoggerRepositoryEx) { - ((LoggerRepositoryEx) repo).getScheduler().schedule(this, - System.currentTimeMillis() + interval, interval); - } else { - this.getLogger().error("{} watchdog requires repository that supports LoggerRepositoryEx", - this.getName()); - } - } - - /** - * Implements the Job interface for the Scheduler. When this method is called - * by the Scheduler it checks the current modification time of the watched - * source with the last recorded modification time. If the modification times - * are different, then the log4j environment is reconfigured using the - * watched source for the configuration data. - */ - public void execute() { - getLogger().debug("FileWatchdog \"{}\" executing", this.getName()); - if (watchedFile.exists()) { - long curModTime = watchedFile.lastModified(); - getLogger().debug("Checking times for watchdog " + this.getName() + - " :(lastModTime - " + lastModTime + ") ?? (curModTime - " + - curModTime + ")"); - if (curModTime != lastModTime) { - if (reconfigure()) { - lastModTime = curModTime; - getLogger().debug("Reconfiguration successful for watchdog " + - this.getName()); - } else { - getLogger().debug("Reconfiguration not successful for watchdog " + - this.getName() + ", not updating mod time"); - } - } else { - getLogger().debug("Times matched, doing nothing"); - } - } else { - getLogger().debug("File does not exist, doing nothing"); - } - } - /** - * Shutdown this watchdog. Since implemented as a scheduled Job, this method - * simply removes the watchdog from the Scheduler. - */ - public void shutdown() { - LoggerRepository repo = getLoggerRepository(); - if (repo instanceof LoggerRepositoryEx) { - ((LoggerRepositoryEx) repo).getScheduler().delete(this); - } - } - /** - * Reconfigures the log4j environment using the file as the source of the - * configuration data. - */ - public boolean reconfigure() { - InputStream stream = null; - try { - stream = new FileInputStream(watchedFile); - return reconfigureByStream(stream); - } catch (FileNotFoundException e) { - return false; - } finally { - if (stream != null) { - try { - stream.close(); - } catch (IOException e2) { - // ignore - } - } - } - } -} diff --git a/src/main/java/org/apache/log4j/watchdog/Watchdog.java b/src/main/java/org/apache/log4j/watchdog/Watchdog.java deleted file mode 100644 index 9e21206026..0000000000 --- a/src/main/java/org/apache/log4j/watchdog/Watchdog.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.watchdog; - -import org.apache.log4j.plugins.Plugin; - -/** - Defines the required interface for all Watchdog objects. - -

  • -#end - -#macro (printMeta $metaElement) - -#end - -#macro (faqIndex $root) - - #set( $section = 1 ) - - #foreach ( $s in $root.getChild("body").getChildren() ) - #if ($s.getName().equals("faqSection")) - #set( $counter = 1 ) -
    -
    - Section $section. $s.getChild("title").getContent() -
    - - #foreach ( $q in $s.getChildren() ) - #if ($q.getName().equals("question")) - - - -
    Question $section.$counter$q.getChild("title").getContent()
    - #set( $counter = $counter + 1 ) - #end - #end - #set( $section = $section + 1 ) - #end - #end -#end - -#macro (faqContents $root) -
    - - #set( $section = 1 ) - - #foreach ( $s in $root.getChild("body").getChildren() ) - #if ($s.getName().equals("faqSection")) - #set( $counter = 1 ) -
    - Section $section. $s.getChild("title").getContent() -
    - #foreach ( $i in $s.getChildren() ) - #if ($i.getName().equals("question")) - - #set( $counter = $counter + 1 ) - $i.getChild("answer").getContent() - #elseif ($i.getName().equals("text")) - $i.getContent() - #end - #end - #set( $section = $section + 1 ) - #end - #end -#end - - -#macro (messages $root) - #foreach ( $m in $root.getChild("body").getChildren() ) - #if ($m.getName().equals("message")) - -
    - $m.getChild("explanation").getContent() -
    - #end - #end -#end - -#macro (document) - #set ($properties = $root.getChild("properties") ) - - - - - - - - - #set ($authors = $properties.getChildren("author")) - #foreach ( $au in $authors ) - #metaauthor ( $au.getText() $au.getAttributeValue("email") ) - #end - - #set ($metas = $root.getChildren("meta")) - - ## Parse meta directives such as - ## - #foreach ($meta in $metas) #printMeta($meta) #end - - ## Support for tags. - #if ($properties.getChild("base")) - #set ($url = $properties.getChild("base").getAttributeValue("href")) - - #end - - - #set ($links = $properties.getChildren("link")) - #foreach ( $l in $links ) - - #end - - - $project.getChild("title").getText() - $properties.getChild("title").getText() - - - - - #getProjectImage() - - -
    -
    - - #foreach ( $item in $root.getChild("body").getChildren() ) - #if ($item.getName().equals("img")) - #image ($item) - #elseif ($item.getName().equals("section")) - #section ($item) - #elseif ($item.getName().equals("faqSection")) - ## do nothing, we'll handle the faq later - #elseif ($item.getName().equals("message")) - ## do nothing, we'll handle the faq later - #else - $item - #end - #end - - #faqIndex ($root) - #faqContents ($root) - #messages ($root) - -## #if ($root.getChild("body").getChild("titleSection")) -## #set ($titleSection = $root.getChild("body").getChild("titleSection")) -## #titleSection($titleSection) -## #end -## -## #set ($allSections = $root.getChild("body").getChildren("section")) -## #foreach ( $section in $allSections ) -## #section ($section) -## #end - - - -
    - Copyright © 1999-2006, Apache Software Foundation.
    -Licensed under the Apache License, Version 2.0. -
    - - - - - #makeNavigationBar() - - - -#end - - - - - diff --git a/src/xdocs/ugli.xml b/src/xdocs/ugli.xml deleted file mode 100644 index e973eadb56..0000000000 --- a/src/xdocs/ugli.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Ceki Gülcü - Universal and Generic Logging Interface (UGLI) - - - - -

    Universal and Generic Logging Interface (UGLI)

    - -

    The Universal and Generic Logging Interface effort has been - renamed as SLF4J and moved to slf4j.org.

    - - - -
    diff --git a/tests/.cvsignore b/tests/.cvsignore deleted file mode 100644 index e3fa3d38fb..0000000000 --- a/tests/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -goEnv -build.properties -output -classes -lib -coverage -log4j.db* - diff --git a/tests/README b/tests/README index 0dcbb33166..fcca3958ba 100644 --- a/tests/README +++ b/tests/README @@ -1,58 +1,40 @@ -This directory (./tests/) contains a series of log4j test cases. ------------------------------------------------------------------------- -NOTE: The compilation and execution of tests must be performed from - within the tests/ directory, that is from the directory where - this README file is located. ------------------------------------------------------------------------- +This directory contains a series of log4j test cases. -============= Prerequisites ============= -Ant ---- - Jakarta-ant is used to compile and run the tests. Jakarta-ant version -1.5.1 was used to compile and run the tests. - -XML parser ----------- +1.4.0 was used to compile and run the tests. The optional +jakarta-ant-1.4-optional.jar file is required to be in the +$ANT_HOME/lib directory where ANT_HOME envrironment variable point to +the directory where you installed jakarta-ant. The tests cases as well running ant require a JAXP compatible parser. Such a parser is placed on the classpath by the shell or batch script that invokes ant, namely $ANT_HOME/bin/ant on UNIX and %ANT_HOME%/bin/ant.bat on Windows. -Junit ------ - The test cases are based on Junit version 3.7+. -Note: You must have junit.jar and the class files for the task -in the same classpath. You can do one of: - - 1) Put both junit.jar and the optional tasks jar file in ANT_HOME/lib. - - 2) Do not put either in ANT_HOME/lib, and instead include their - locations in your CLASSPATH environment variable. - - 3) Do neither of the above, and instead, specify their locations using - a element in the build file. See the FAQ for details. - -The first option is probably the easiest. - -jakarta-oro ------------ +IMPORTANT: You need to place junit.jar in your CLASSPATH environment +variable. The test cases perform some regular expression based filtering. This requires jakarta-oro. Version-2.0.5 was used when writing the -tests. - -You need to set the jakarta.oro.jar property (found in the +tests. You need to have jakarta.oro.jar property (found in the build.properties file) to point to jakarta-oro.jar. See the file build.properties.sample for an example of a build.properties file. +Assuming jakarta-ant is installed properly, depending on your platform +type $ANT_HOME/bin/ant or %ANT_HOME%/bin/ant.bat to see the available +commands. + +------------------------------------------------------------------------ +NOTE: The compilation and execution of tests must be performed from + within the tests/ directory, that is from the directory where + this README file is located. +------------------------------------------------------------------------ Writing a new test case ======================= @@ -69,39 +51,3 @@ by removing date and time information. To automatically run your test case with the rest of the log4j test cases, you need to modify tests/build.xml. - -=================== -OPTIONAL Test cases -=================== - -Some test cases are also dependent on other external projects and -jars. If you would like to run the optional tests, then these jars -should be places in the ./tests/lib directory. - -Jetty (OPTIONAL) ------ - -We embed jetty to tests log4j within a web-application. - -jetty - http://jetty.mortbay.org/jetty/ - Version 4.2.22 was used when -writing the tests. You will need both the org.mortbay.jetty.jar and -org.mortbay.jetty.plus.jar - -Database testing ----------------- - -For the various DB tests you need to place the appropriate -JDBC drivers in ./tests/lib/ directory. - -Testing JNDIConnectionSource requires JNDI File System Service -Provider, 1.2 Beta 3, which can be downloaded from: - -http://java.sun.com/products/jndi/downloads/index.html - -Click on "Download JNDI 1.2.1 & More" - -Once you obtained the JNDI File System Service Provider place -the files fscontext.jar and providerutil.jar in the ./tests/lib/ -directory. - - diff --git a/tests/build.properties.sample b/tests/build.properties.sample index a7685afdd7..5f0f1b879d 100644 --- a/tests/build.properties.sample +++ b/tests/build.properties.sample @@ -1,23 +1,40 @@ -deprecation=on - +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# # # by default assume that all necessary dependencies # are relative to the user's home directory # -lib.home.dir=${user.home} - -xml.home=/java/xerces-2_6_2 -xml-api.jar=${xml.home}/xml-apis.jar -xml-impl.jar=${xml.home}/xercesImpl.jar +lib.home.dir=/java -jakarta-oro.jar=${lib.home.dir}/jakarta-oro-2.0.8/jakarta-oro-2.0.8.jar -# JavaMail API OPTIONAL; required to build the SMTPAppender -javamail.jar=${lib.home.dir}/javamail-1.3.2/mail.jar -activation.jar=${lib.home.dir}/jaf-1.0.2/activation.jar +# The jaxp interface and a jaxp parser are required +# to build the DOMConfigurator. +# +# modern equivalents are xml-commons-apis.jar +# and xercesImpl.jar +jaxp.home=${lib.home.dir}/crimson-1.1.3 +jaxp.jaxp.jar=${jaxp.home}/crimson.jar +jaxp.parser.jar=${jaxp.home}/crimson.jar -# SLF4J api -slf4j-api.jar=${lib.home.dir}/slf4j-1.0-beta2/slf4j-nop.jar +jakarta.oro.jar=${lib.home.dir}/jakarta-oro-2.0.8/jakarta-oro-2.0.8.jar +clover.jar=${lib.home.dir}/clover-1.3.8/lib/clover.jar +deprecation=on +# junit must be on the classpath or specified with -lib +# only needs to be set here for JDK 1.1. +junit.jar=${lib.home.dir}/junit3.8.1/junit.jar # # Jalopy source code reformatter diff --git a/tests/build.xml b/tests/build.xml index 46b558c6ef..74a7139dce 100644 --- a/tests/build.xml +++ b/tests/build.xml @@ -1,146 +1,118 @@ - + - + - + - + - + - - - - + + + + + + + + + - - - + + + - - - - + - - - - - + + - - - + + - + - + + + + + - - - - - - - + - - + - - - + + + - - These are the targets supported by this ANT build scpript: - - build - compile all project files, if a certain library is missing, - then the compilation of its dependents are skipped. - - regression - Run regression tests which check large parts of log4j. - - runAll - run all available tests - - coverageReport - Runs all tests and generates coverage report. - - - - - - - - - - - - + These are the targets supported by this ANT build scpript: - - - - - - - + build - compile all project files, if a certain library is missing, + then the compilation of its dependents are skipped. - - Please make sure to that jakarta-oro.jar is available. You can either - place it in the ./tests/lib/ directory or alternatively set the - "jakarta-oro.jar" property to point to it. - - + regression - Run regression tests which check large parts of log4j. - - - - + runAll - run all available tests - - Could not find junit classes. Is the file junit.jar missing? - See the documentation for the junit task in the Apache Ant Manual. - + Specify the log4j.jar property to test an arbitrary jar, + otherwise the parent log4j will be built and tested. + - + + + + + + + + + + + + @@ -153,648 +125,304 @@ - - - - - + + + - + destdir="./classes" + deprecation="${deprecation}" + target="${javac.target}" + source="${javac.source}" + debug="on" + excludes="${excludes}"> - - + + - - + + - - - - - - - - - - - - - + - + - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + - - - - - - - - - - - - - - - - - - - - + + - + - - - + + + - + - - + + - + - - - - + - + - - + + - + - - - - - - - - - - - - + + - + - - + + - - + + - + - - + + - + - - + + - + - - + + - - + + - + - - - + + + - - - + + - + - - - - + + + + - - - - - - + + + + + + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - + + - + - - - - - - - - - - + + - - + + - - + + - + - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - + @@ -802,7 +430,8 @@ - + @@ -810,75 +439,58 @@ - + - - - - + + - - + + - - - - - - + - + + + + + + + + + + + + + + + + + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -889,8 +501,8 @@ - clover.jar must be in the classpath and -Dclover.jar should be - specified or clover.jar placed in the lib directory. A version of clover + clover.jar must be in the classpath and should also be + placed in the lib directory. A version of clover (http://www.cenqua.com/clover) for use with ASF projects is available from the committers/donated-licenses/clover module in the SVN repository. @@ -909,12 +521,13 @@ - + + - + Specify files to reformat with -Djalopy.files=PATTERN. @@ -927,7 +540,7 @@ Specify files to reformat with -Djalopy.files=PATTERN. @@ -935,18 +548,18 @@ Specify files to reformat with -Djalopy.files=PATTERN. - + - + - + - + diff --git a/tests/db.xml b/tests/db.xml deleted file mode 100644 index 45aab9d4f3..0000000000 --- a/tests/db.xml +++ /dev/null @@ -1,232 +0,0 @@ - - - - - - - - - - - - - - - - - - This build file cannot be invoked directly but only through - its parent build file, build.xml. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Build aborted by user. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Could not find HSQLDB driver. - No point in running HSQLDB tests. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Could not find MySQL driver. - No point in running MySQL tests. - - - - - - - - - - - - - - - - - - - - - - - - - - - Could not find PostgreSQL driver. - No point in running PostgreSQL tests. - - - - - - - - - - - - - - - - - - - - - - - - Could not find Oracle driver. - No point in running Oracle tests. - - - - - - - - - - - - - - - - - - - - - - - - - Could not find MsSQL driver. - No point in running MsSQL tests. - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/input/RFA1.properties b/tests/input/RFA1.properties index d4e3fa331c..35a30d6a99 100644 --- a/tests/input/RFA1.properties +++ b/tests/input/RFA1.properties @@ -1,3 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. log4j.rootLogger=DEBUG, testAppender log4j.appender.testAppender=org.apache.log4j.RollingFileAppender log4j.appender.testAppender.file=output/RFA-test1.log diff --git a/tests/input/compress1.copy b/tests/input/compress1.copy deleted file mode 100644 index 03eda79afd..0000000000 --- a/tests/input/compress1.copy +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ \ No newline at end of file diff --git a/tests/input/compress2.copy b/tests/input/compress2.copy deleted file mode 100644 index cb064c7b95..0000000000 --- a/tests/input/compress2.copy +++ /dev/null @@ -1,129 +0,0 @@ - -=========== -Using log4j -=========== - -1) First untar or unzip the distribution file. - -2) Assuming you chose to extract the distribution in to the - PATH_OF_YOUR_CHOICE, untarring the distribution file should create - a jakarta-log4j-VERSION directory, where VERSION is the 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) 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. - - import org.apache.log4j.Logger; - import org.apache.log4j.BasicConfigurator; - - public class Hello { - - static Logger logger = Logger.getLogger(Hello.class); - - public - static - void main(String argv[]) { - BasicConfigurator.configure(); - logger.debug("Hello world."); - logger.info("What a beatiful day."); - } - } - - - After compilation, try it out by issuing the command - - java Hello - - You should see log statements appearing on the console. - -5) Refer to the javadoc documentation and the user manual on how to - include log statements in your own code. - -========= -JAR files -========= - -The log4j distribution comes with one jar file: log4j-VERSION.jar -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 -"org.apache.log4j.performance" packages. - -================== -log4j dependencies -================== - -Log4j is based on JDK 1.1 with the following additional requirements: - - ---------------------------- - Package org.apache.log4j.xml - ---------------------------- - - 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. - - The DOMConfigurator.configure(String filename) method and its variants - require a JAXP compatible XMLparser, for example the Apache Xerces - parser. Compiling the DOMConfigurator requires the presence of a - JAXP parser in the classpath. - - Given that Ant already ships with a compatible XML parser, you do - *not* need to worry about setting the parser when building, - i.e. compiling, log4j. - - ------------ - SMTPAppender - ------------ - - 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: - - http://java.sun.com/products/javamail/ - - and the JavaBeans Activation Framework at: - - http://java.sun.com/beans/glasgow/jaf.html - - ----------- - JMSAppender - ----------- - - The JMSAppender requires the JMS API as well as JNDI. The JMS API - is usually bundled with the products of the vendors listed under - - http://java.sun.com/products/jms/vendors.html - - ----------------------- - JUnit testing framework - ----------------------- - - Log4j uses the JUnit framework version 3.7 for internal unit - 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 - -============== -Building log4j -============== - -Like most java appilicatios today, log4j relies on ANT as its build -tool. ANT is availale from "http://jakarta.apache.org/ant/". ANT -requires a build file called build.xml which is part of this -distribution. Required components from other projects are specified in -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 -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/tests/input/compress3.copy b/tests/input/compress3.copy deleted file mode 100644 index 8d3e0e4850..0000000000 --- a/tests/input/compress3.copy +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -=========== -Using log4j -=========== - -1) First untar or unzip the distribution file. - -2) Assuming you chose to extract the distribution in to the - PATH_OF_YOUR_CHOICE, untarring the distribution file should create - a jakarta-log4j-VERSION directory, where VERSION is the 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) 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. - - import org.apache.log4j.Logger; - import org.apache.log4j.BasicConfigurator; - - public class Hello { - - static Logger logger = Logger.getLogger(Hello.class); - - public - static - void main(String argv[]) { - BasicConfigurator.configure(); - logger.debug("Hello world."); - logger.info("What a beatiful day."); - } - } - - - After compilation, try it out by issuing the command - - java Hello - - You should see log statements appearing on the console. - -5) Refer to the javadoc documentation and the user manual on how to - include log statements in your own code. - -========= -JAR files -========= - -The log4j distribution comes with one jar file: log4j-VERSION.jar -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 -"org.apache.log4j.performance" packages. - -================== -log4j dependencies -================== - -Log4j is based on JDK 1.1 with the following additional requirements: - - ---------------------------- - Package org.apache.log4j.xml - ---------------------------- - - 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. - - The DOMConfigurator.configure(String filename) method and its variants - require a JAXP compatible XMLparser, for example the Apache Xerces - parser. Compiling the DOMConfigurator requires the presence of a - JAXP parser in the classpath. - - Given that Ant already ships with a compatible XML parser, you do - *not* need to worry about setting the parser when building, - i.e. compiling, log4j. - - ------------ - SMTPAppender - ------------ - - 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: - - http://java.sun.com/products/javamail/ - - and the JavaBeans Activation Framework at: - - http://java.sun.com/beans/glasgow/jaf.html - - ----------- - JMSAppender - ----------- - - The JMSAppender requires the JMS API as well as JNDI. The JMS API - is usually bundled with the products of the vendors listed under - - http://java.sun.com/products/jms/vendors.html - - ----------------------- - JUnit testing framework - ----------------------- - - Log4j uses the JUnit framework version 3.7 for internal unit - 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 - -============== -Building log4j -============== - -Like most java appilicatios today, log4j relies on ANT as its build -tool. ANT is availale from "http://jakarta.apache.org/ant/". ANT -requires a build file called build.xml which is part of this -distribution. Required components from other projects are specified in -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 -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/tests/input/db/.cvsignore b/tests/input/db/.cvsignore deleted file mode 100644 index c05724cb5e..0000000000 --- a/tests/input/db/.cvsignore +++ /dev/null @@ -1,4 +0,0 @@ -mysql.properties -postgresql.properties -hsqldb.properties -db.properties diff --git a/tests/input/db/append-with-c3p0.xml b/tests/input/db/append-with-c3p0.xml deleted file mode 100644 index ef2986e41f..0000000000 --- a/tests/input/db/append-with-c3p0.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/db/append-with-datasource1.xml b/tests/input/db/append-with-datasource1.xml deleted file mode 100644 index 556ddd910c..0000000000 --- a/tests/input/db/append-with-datasource1.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/db/append-with-drivermanager1.xml b/tests/input/db/append-with-drivermanager1.xml deleted file mode 100644 index c095e51f70..0000000000 --- a/tests/input/db/append-with-drivermanager1.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/db/append-with-jndi1.xml b/tests/input/db/append-with-jndi1.xml deleted file mode 100644 index 75fb879f1f..0000000000 --- a/tests/input/db/append-with-jndi1.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/db/append-with-pooled-datasource1.xml b/tests/input/db/append-with-pooled-datasource1.xml deleted file mode 100644 index 5afebc83df..0000000000 --- a/tests/input/db/append-with-pooled-datasource1.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/db/deleteTables.sql b/tests/input/db/deleteTables.sql deleted file mode 100644 index 3e4dc5dfa8..0000000000 --- a/tests/input/db/deleteTables.sql +++ /dev/null @@ -1,4 +0,0 @@ - -delete from logging_event_exception; -delete from logging_event_property; -delete from logging_event; diff --git a/tests/input/db/hsqldb.properties.sample b/tests/input/db/hsqldb.properties.sample deleted file mode 100644 index 9dc6553a8d..0000000000 --- a/tests/input/db/hsqldb.properties.sample +++ /dev/null @@ -1,11 +0,0 @@ -# If you would like to test DBAppender/DBReceiver for HSQLDB, then set -# the url and user parameters for your local environment and copy this -# file to "hsqldb.properties". - -# The JDBC driver class for HSQLDB -driverClass=org.hsqldb.jdbcDriver - -# The following parameters should be set for your machine. -url=jdbc:hsqldb:hsql://localhost -user=sa -password= \ No newline at end of file diff --git a/tests/input/db/mysql.properties.sample b/tests/input/db/mysql.properties.sample deleted file mode 100644 index 65b9688afd..0000000000 --- a/tests/input/db/mysql.properties.sample +++ /dev/null @@ -1,17 +0,0 @@ -# If you would like to test DBAppender/DBReceiver for MySQL, then -# set the url and user parameters for your local environment and -# copy this file to "mysql.properties". - -# The JDBC driver class for MySQL -driverClass=com.mysql.jdbc.Driver - -# The DataSource class for MySQL -dataSourceClass=com.mysql.jdbc.jdbc2.optional.MysqlDataSource - -# Native pooled DataSource class for MySQL -pooledDataSourceClass=com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource - -# The following parameters should be set for your machine. -url=jdbc:mysql:///test -user=root -password= \ No newline at end of file diff --git a/tests/input/db/oracle.properties.sample b/tests/input/db/oracle.properties.sample deleted file mode 100644 index f4c7a08e86..0000000000 --- a/tests/input/db/oracle.properties.sample +++ /dev/null @@ -1,25 +0,0 @@ -**************************************************************************** -# If you would like to test DBAppender/DBReceiver for Oracle, then -# set the url and user parameters for your local environment and -# copy this file to "oracle.properties". -# -# Tested successfully on Oracle9i Release 9.2.0.3.0 by James Stauffer. -# -# The following parameters should be set for your machine. - -url=jdbc:oracle:thin:@goofy:1521:dwebec -user=john -password=xxx - -# Ususally, there is NO need to change anything below this line -# ************************************************************** - -# The JDBC driver class for Oracle -driverClass=oracle.jdbc.driver.OracleDriver - -dataSourceClass=oracle.jdbc.pool.OracleDataSource -pooledDataSourceClass=oracle.jdbc.pool.OracleConnectionCacheImpl - -# oracle.jdbc.pool.OracleDataSource and OracleConnectionCacheImpl -# name the url property as "URL" -url-key=URL \ No newline at end of file diff --git a/tests/input/db/postgresql.properties.sample b/tests/input/db/postgresql.properties.sample deleted file mode 100644 index 0d23485eb5..0000000000 --- a/tests/input/db/postgresql.properties.sample +++ /dev/null @@ -1,28 +0,0 @@ -# If you would like to test DBAppender/DBReceiver with PostgreSQL, then -# set the url and user parameters for your local environment and -# copy this file to "postgresql.properties". - -# The JDBC driver class for PostgreSQL -driverClass=org.postgresql.Driver - -# The DataSource class for PostgreSQL -dataSourceClass=org.postgresql.jdbc2.optional.SimpleDataSource - -# Native pooled DataSource class for PostgreSQL -pooledDataSourceClass=org.postgresql.jdbc3.Jdbc3PoolingDataSource - -# ======================================================= -# The following parameters should be set for your machine. -# ======================================================= - -# you need to set both the url and serverName and databaseName -# this is redundant but allows the same properties file to be used -# in different config files -url=jdbc:postgresql://gil/test -serverName=gil -databaseName=test - - -user=pg -password=pg - diff --git a/tests/input/db/read-with-datasource1.xml b/tests/input/db/read-with-datasource1.xml deleted file mode 100644 index f35c488cf2..0000000000 --- a/tests/input/db/read-with-datasource1.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/db/read-with-drivermanager1.xml b/tests/input/db/read-with-drivermanager1.xml deleted file mode 100644 index 136c7842ae..0000000000 --- a/tests/input/db/read-with-drivermanager1.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/db/read-with-jndi1.xml b/tests/input/db/read-with-jndi1.xml deleted file mode 100644 index b14fc8d9ca..0000000000 --- a/tests/input/db/read-with-jndi1.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/db/read-with-pooled-datasource1.xml b/tests/input/db/read-with-pooled-datasource1.xml deleted file mode 100644 index 2d4f769bde..0000000000 --- a/tests/input/db/read-with-pooled-datasource1.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/defaultInit3.properties b/tests/input/defaultInit3.properties index ce38951cac..3c2e43376d 100644 --- a/tests/input/defaultInit3.properties +++ b/tests/input/defaultInit3.properties @@ -1,3 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. log4j.rootCategory=DEBUG, D3 log4j.appender.D3=org.apache.log4j.FileAppender diff --git a/tests/input/fallback1.properties b/tests/input/fallback1.properties new file mode 100644 index 0000000000..bf520ae407 --- /dev/null +++ b/tests/input/fallback1.properties @@ -0,0 +1,32 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.debug=true +log4j.appender.PRIMARY=org.apache.log4j.FileAppender +log4j.appender.PRIMARY.errorhandler=org.apache.log4j.varia.FallbackErrorHandler +log4j.appender.PRIMARY.errorhandler.root-ref=true +log4j.appender.PRIMARY.errorhandler.appender-ref=FALLBACK +log4j.appender.PRIMARY.file=/xyz/:x.log +log4j.appender.PRIMARY.append=false +log4j.appender.PRIMARY.layout=org.apache.log4j.PatternLayout +log4j.appender.PRIMARY.layout.conversionPattern=%-5p %c{2} - %m%n + +log4j.appender.FALLBACK=org.apache.log4j.FileAppender +log4j.appender.FALLBACK.File=output/temp +log4j.appender.FALLBACK.Append=false +log4j.appender.FALLBACK.layout=org.apache.log4j.PatternLayout +log4j.appender.FALLBACK.layout.ConversionPattern=FALLBACK - %c - %m%n + +log4j.rootLogger=DEBUG, PRIMARY diff --git a/tests/input/filter/simpleFilter1.xml b/tests/input/filter/simpleFilter1.xml deleted file mode 100644 index 8e8d1c24e3..0000000000 --- a/tests/input/filter/simpleFilter1.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/filter/simpleFilter10.xml b/tests/input/filter/simpleFilter10.xml deleted file mode 100644 index 426c861f70..0000000000 --- a/tests/input/filter/simpleFilter10.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/filter/simpleFilter11.xml b/tests/input/filter/simpleFilter11.xml deleted file mode 100644 index 8b7ad12fb6..0000000000 --- a/tests/input/filter/simpleFilter11.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/filter/simpleFilter12.xml b/tests/input/filter/simpleFilter12.xml deleted file mode 100644 index 0d7c9b1d83..0000000000 --- a/tests/input/filter/simpleFilter12.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/filter/simpleFilter2.xml b/tests/input/filter/simpleFilter2.xml deleted file mode 100644 index 16c2599bd0..0000000000 --- a/tests/input/filter/simpleFilter2.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/filter/simpleFilter3.xml b/tests/input/filter/simpleFilter3.xml deleted file mode 100644 index fa58d7a906..0000000000 --- a/tests/input/filter/simpleFilter3.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/filter/simpleFilter4.xml b/tests/input/filter/simpleFilter4.xml deleted file mode 100644 index da01c2ff82..0000000000 --- a/tests/input/filter/simpleFilter4.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/filter/simpleFilter5.xml b/tests/input/filter/simpleFilter5.xml deleted file mode 100644 index d1a34e32c0..0000000000 --- a/tests/input/filter/simpleFilter5.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/filter/simpleFilter6.xml b/tests/input/filter/simpleFilter6.xml deleted file mode 100644 index 2a45efee60..0000000000 --- a/tests/input/filter/simpleFilter6.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/filter/simpleFilter7.xml b/tests/input/filter/simpleFilter7.xml deleted file mode 100644 index 64e7c2b94f..0000000000 --- a/tests/input/filter/simpleFilter7.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/filter/simpleFilter8.xml b/tests/input/filter/simpleFilter8.xml deleted file mode 100644 index 84d62bbe04..0000000000 --- a/tests/input/filter/simpleFilter8.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/filter/simpleFilter9.xml b/tests/input/filter/simpleFilter9.xml deleted file mode 100644 index 1c4f894a43..0000000000 --- a/tests/input/filter/simpleFilter9.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/filter1.properties b/tests/input/filter1.properties new file mode 100644 index 0000000000..0bd6b56fd1 --- /dev/null +++ b/tests/input/filter1.properties @@ -0,0 +1,32 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.appender.ROLLING=org.apache.log4j.PropertyConfiguratorTest$RollingFileAppender +log4j.appender.ROLLING.append=false +log4j.appender.ROLLING.rollingPolicy=org.apache.log4j.PropertyConfiguratorTest$FixedWindowRollingPolicy +log4j.appender.ROLLING.rollingPolicy.activeFileName=filterBase-test1.log +log4j.appender.ROLLING.rollingPolicy.fileNamePattern=filterBased-test1.%i +log4j.appender.ROLLING.rollingPolicy.minIndex=0 +log4j.appender.ROLLING.triggeringPolicy=org.apache.log4j.PropertyConfiguratorTest$FilterBasedTriggeringPolicy +log4j.appender.ROLLING.triggeringPolicy.filter=org.apache.log4j.varia.LevelRangeFilter +log4j.appender.ROLLING.triggeringPolicy.filter.levelMin=info +log4j.appender.ROLLING.layout=org.apache.log4j.PatternLayout +log4j.appender.ROLLING.layout.ConversionPattern=%m%n +log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender +log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout +log4j.appender.CONSOLE.layout.ConversionPattern=%m%n +log4j.logger.org.apache.log4j.PropertyConfiguratorTest=debug, ROLLING +log4j.additivity.org.apache.log4j.rolling.FilterBasedRollingTest=false +log4j.roolLogger=info, CONSOLE diff --git a/tests/input/hierarchy/hierarchyThreshold1.properties b/tests/input/hierarchy/hierarchyThreshold1.properties deleted file mode 100644 index 69d27e621d..0000000000 --- a/tests/input/hierarchy/hierarchyThreshold1.properties +++ /dev/null @@ -1,12 +0,0 @@ -log4j.threshold=OFF -log4j.rootLogger=,A -log4j.appender.A=org.apache.log4j.FileAppender -log4j.appender.A.File=output/temp -log4j.appender.A.Append=false -log4j.appender.A.layout=org.apache.log4j.PatternLayout -log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/hierarchy/hierarchyThreshold2.properties b/tests/input/hierarchy/hierarchyThreshold2.properties deleted file mode 100644 index 7a2cf0b14f..0000000000 --- a/tests/input/hierarchy/hierarchyThreshold2.properties +++ /dev/null @@ -1,7 +0,0 @@ -log4j.threshold=FATAL -log4j.rootLogger=,A -log4j.appender.A=org.apache.log4j.FileAppender -log4j.appender.A.File=output/temp -log4j.appender.A.Append=false -log4j.appender.A.layout=org.apache.log4j.PatternLayout -log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n \ No newline at end of file diff --git a/tests/input/hierarchy/hierarchyThreshold3.properties b/tests/input/hierarchy/hierarchyThreshold3.properties deleted file mode 100644 index 5acf2fd766..0000000000 --- a/tests/input/hierarchy/hierarchyThreshold3.properties +++ /dev/null @@ -1,7 +0,0 @@ -log4j.threshold=ERROR -log4j.rootLogger=,A -log4j.appender.A=org.apache.log4j.FileAppender -log4j.appender.A.File=output/temp -log4j.appender.A.Append=false -log4j.appender.A.layout=org.apache.log4j.PatternLayout -log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n \ No newline at end of file diff --git a/tests/input/hierarchy/hierarchyThreshold4.properties b/tests/input/hierarchy/hierarchyThreshold4.properties deleted file mode 100644 index 38291d7fd7..0000000000 --- a/tests/input/hierarchy/hierarchyThreshold4.properties +++ /dev/null @@ -1,7 +0,0 @@ -log4j.threshold=WARN -log4j.rootLogger=,A -log4j.appender.A=org.apache.log4j.FileAppender -log4j.appender.A.File=output/temp -log4j.appender.A.Append=false -log4j.appender.A.layout=org.apache.log4j.PatternLayout -log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n \ No newline at end of file diff --git a/tests/input/hierarchy/hierarchyThreshold5.properties b/tests/input/hierarchy/hierarchyThreshold5.properties deleted file mode 100644 index 3be520dad6..0000000000 --- a/tests/input/hierarchy/hierarchyThreshold5.properties +++ /dev/null @@ -1,7 +0,0 @@ -log4j.threshold=INFO -log4j.rootLogger=,A -log4j.appender.A=org.apache.log4j.FileAppender -log4j.appender.A.File=output/temp -log4j.appender.A.Append=false -log4j.appender.A.layout=org.apache.log4j.PatternLayout -log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n \ No newline at end of file diff --git a/tests/input/hierarchy/hierarchyThreshold6.properties b/tests/input/hierarchy/hierarchyThreshold6.properties deleted file mode 100644 index 4d10aa06e4..0000000000 --- a/tests/input/hierarchy/hierarchyThreshold6.properties +++ /dev/null @@ -1,12 +0,0 @@ -log4j.threshold=DEBUG -log4j.rootLogger=,A -log4j.appender.A=org.apache.log4j.FileAppender -log4j.appender.A.File=output/temp -log4j.appender.A.Append=false -log4j.appender.A.layout=org.apache.log4j.PatternLayout -log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/hierarchy/hierarchyThreshold7.properties b/tests/input/hierarchy/hierarchyThreshold7.properties deleted file mode 100644 index 3dbe653ba0..0000000000 --- a/tests/input/hierarchy/hierarchyThreshold7.properties +++ /dev/null @@ -1,12 +0,0 @@ -log4j.threshold=TRACE#org.apache.log4j.xml.XLevel -log4j.rootLogger=ALL,A -log4j.appender.A=org.apache.log4j.FileAppender -log4j.appender.A.File=output/temp -log4j.appender.A.Append=false -log4j.appender.A.layout=org.apache.log4j.PatternLayout -log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/hierarchy/hierarchyThreshold8.properties b/tests/input/hierarchy/hierarchyThreshold8.properties deleted file mode 100644 index d330bbd42b..0000000000 --- a/tests/input/hierarchy/hierarchyThreshold8.properties +++ /dev/null @@ -1,12 +0,0 @@ -log4j.threshold=ALL -log4j.rootLogger=ALL,A -log4j.appender.A=org.apache.log4j.FileAppender -log4j.appender.A.File=output/temp -log4j.appender.A.Append=false -log4j.appender.A.layout=org.apache.log4j.PatternLayout -log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/hierarchyThreshold1.properties b/tests/input/hierarchyThreshold1.properties new file mode 100644 index 0000000000..81a529ecda --- /dev/null +++ b/tests/input/hierarchyThreshold1.properties @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.threshold=OFF +log4j.rootLogger=,A +log4j.appender.A=org.apache.log4j.FileAppender +log4j.appender.A.File=output/temp +log4j.appender.A.Append=false +log4j.appender.A.layout=org.apache.log4j.PatternLayout +log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n \ No newline at end of file diff --git a/tests/input/hierarchyThreshold2.properties b/tests/input/hierarchyThreshold2.properties new file mode 100644 index 0000000000..b79aa7f603 --- /dev/null +++ b/tests/input/hierarchyThreshold2.properties @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.threshold=FATAL +log4j.rootLogger=,A +log4j.appender.A=org.apache.log4j.FileAppender +log4j.appender.A.File=output/temp +log4j.appender.A.Append=false +log4j.appender.A.layout=org.apache.log4j.PatternLayout +log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n \ No newline at end of file diff --git a/tests/input/hierarchyThreshold3.properties b/tests/input/hierarchyThreshold3.properties new file mode 100644 index 0000000000..aae8b4435f --- /dev/null +++ b/tests/input/hierarchyThreshold3.properties @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.threshold=ERROR +log4j.rootLogger=,A +log4j.appender.A=org.apache.log4j.FileAppender +log4j.appender.A.File=output/temp +log4j.appender.A.Append=false +log4j.appender.A.layout=org.apache.log4j.PatternLayout +log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n \ No newline at end of file diff --git a/tests/input/hierarchyThreshold4.properties b/tests/input/hierarchyThreshold4.properties new file mode 100644 index 0000000000..ba54f13321 --- /dev/null +++ b/tests/input/hierarchyThreshold4.properties @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.threshold=WARN +log4j.rootLogger=,A +log4j.appender.A=org.apache.log4j.FileAppender +log4j.appender.A.File=output/temp +log4j.appender.A.Append=false +log4j.appender.A.layout=org.apache.log4j.PatternLayout +log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n \ No newline at end of file diff --git a/tests/input/hierarchyThreshold5.properties b/tests/input/hierarchyThreshold5.properties new file mode 100644 index 0000000000..f4ef8587f1 --- /dev/null +++ b/tests/input/hierarchyThreshold5.properties @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.threshold=INFO +log4j.rootLogger=,A +log4j.appender.A=org.apache.log4j.FileAppender +log4j.appender.A.File=output/temp +log4j.appender.A.Append=false +log4j.appender.A.layout=org.apache.log4j.PatternLayout +log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n \ No newline at end of file diff --git a/tests/input/hierarchyThreshold6.properties b/tests/input/hierarchyThreshold6.properties new file mode 100644 index 0000000000..3cc6122a21 --- /dev/null +++ b/tests/input/hierarchyThreshold6.properties @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.threshold=DEBUG +log4j.rootLogger=,A +log4j.appender.A=org.apache.log4j.FileAppender +log4j.appender.A.File=output/temp +log4j.appender.A.Append=false +log4j.appender.A.layout=org.apache.log4j.PatternLayout +log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n \ No newline at end of file diff --git a/tests/input/hierarchyThreshold7.properties b/tests/input/hierarchyThreshold7.properties new file mode 100644 index 0000000000..3ffcdfb003 --- /dev/null +++ b/tests/input/hierarchyThreshold7.properties @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.threshold=TRACE#org.apache.log4j.xml.XLevel +log4j.rootLogger=ALL,A +log4j.appender.A=org.apache.log4j.FileAppender +log4j.appender.A.File=output/temp +log4j.appender.A.Append=false +log4j.appender.A.layout=org.apache.log4j.PatternLayout +log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n diff --git a/tests/input/hierarchyThreshold8.properties b/tests/input/hierarchyThreshold8.properties new file mode 100644 index 0000000000..a21eed9276 --- /dev/null +++ b/tests/input/hierarchyThreshold8.properties @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.threshold=ALL +log4j.rootLogger=ALL,A +log4j.appender.A=org.apache.log4j.FileAppender +log4j.appender.A.File=output/temp +log4j.appender.A.Append=false +log4j.appender.A.layout=org.apache.log4j.PatternLayout +log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n \ No newline at end of file diff --git a/tests/input/joran/asyncTest.xml b/tests/input/joran/asyncTest.xml deleted file mode 100644 index 86f3c3f768..0000000000 --- a/tests/input/joran/asyncTest.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/input/joran/badEnd1.xml b/tests/input/joran/badEnd1.xml deleted file mode 100644 index f81500d90f..0000000000 --- a/tests/input/joran/badEnd1.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/input/joran/badEnd2.xml b/tests/input/joran/badEnd2.xml deleted file mode 100644 index 80ebd92951..0000000000 --- a/tests/input/joran/badEnd2.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/input/joran/basicLoop.xml b/tests/input/joran/basicLoop.xml deleted file mode 100644 index 9ec9e8f11e..0000000000 --- a/tests/input/joran/basicLoop.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/tests/input/joran/conversionRule.xml b/tests/input/joran/conversionRule.xml deleted file mode 100644 index b8c1aff147..0000000000 --- a/tests/input/joran/conversionRule.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/input/joran/exception1.xml b/tests/input/joran/exception1.xml deleted file mode 100644 index c3f068bb25..0000000000 --- a/tests/input/joran/exception1.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/input/joran/illFormed.xml b/tests/input/joran/illFormed.xml deleted file mode 100644 index 675feb87c1..0000000000 --- a/tests/input/joran/illFormed.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - diff --git a/tests/input/joran/newRule1.xml b/tests/input/joran/newRule1.xml deleted file mode 100644 index 152a32dd54..0000000000 --- a/tests/input/joran/newRule1.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/tests/input/joran/parser1.xml b/tests/input/joran/parser1.xml deleted file mode 100644 index dce91b5586..0000000000 --- a/tests/input/joran/parser1.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/joran/parser2.xml b/tests/input/joran/parser2.xml deleted file mode 100644 index 7bcb6d36eb..0000000000 --- a/tests/input/joran/parser2.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - asdfasdf - - - asdfasdf - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/joran/parser3.xml b/tests/input/joran/parser3.xml deleted file mode 100644 index 8cce4473e3..0000000000 --- a/tests/input/joran/parser3.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/input/joran/resourceBundle.xml b/tests/input/joran/resourceBundle.xml deleted file mode 100644 index e071879def..0000000000 --- a/tests/input/joran/resourceBundle.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/joran/simple1.xml b/tests/input/joran/simple1.xml deleted file mode 100644 index 1a5bc2329c..0000000000 --- a/tests/input/joran/simple1.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/tests/input/joran/simple2.xml b/tests/input/joran/simple2.xml deleted file mode 100644 index 5e839e8ced..0000000000 --- a/tests/input/joran/simple2.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/tests/input/multiplex/configTest-1.xml b/tests/input/multiplex/configTest-1.xml deleted file mode 100644 index e286ef748e..0000000000 --- a/tests/input/multiplex/configTest-1.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/input/ndc/NDC1.properties b/tests/input/ndc/NDC1.properties deleted file mode 100644 index 873fd4f853..0000000000 --- a/tests/input/ndc/NDC1.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootCategory=DEBUG, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.file=output/temp -log4j.appender.testAppender.Append=false -log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.testAppender.layout.ConversionPattern=%-5p %x - %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/net/socketServer1.properties b/tests/input/net/socketServer1.properties deleted file mode 100644 index b7bf307e99..0000000000 --- a/tests/input/net/socketServer1.properties +++ /dev/null @@ -1,14 +0,0 @@ -log4j.rootLogger=DEBUG, A -log4j.logger.org.apache.log4j.test.ShortSocketServer=WARN -log4j.logger.org.apache.log4j.net.SocketNode=WARN -log4j.appender.A=org.apache.log4j.FileAppender -log4j.appender.A.file=output/temp -log4j.appender.A.Append=false -log4j.appender.A.layout=org.apache.log4j.PatternLayout -log4j.appender.A.layout.ConversionPattern=%5p %x [%t] %c %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO -log4j.logger.org.apache.log4j.net.ShortSocketServer=INFO \ No newline at end of file diff --git a/tests/input/net/socketServer2.properties b/tests/input/net/socketServer2.properties deleted file mode 100644 index 48e0d3acee..0000000000 --- a/tests/input/net/socketServer2.properties +++ /dev/null @@ -1,14 +0,0 @@ -log4j.rootLogger=DEBUG, A -log4j.logger.org.apache.log4j.test.ShortSocketServer=WARN -log4j.logger.org.apache.log4j.net.SocketNode=WARN -log4j.appender.A=org.apache.log4j.FileAppender -log4j.appender.A.file=output/temp -log4j.appender.A.Append=false -log4j.appender.A.layout=org.apache.log4j.PatternLayout -log4j.appender.A.layout.ConversionPattern=%5p %x [%t] %C (%F:%L) %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO -log4j.logger.org.apache.log4j.net.ShortSocketServer=INFO \ No newline at end of file diff --git a/tests/input/net/socketServer3.properties b/tests/input/net/socketServer3.properties deleted file mode 100644 index 7e63253232..0000000000 --- a/tests/input/net/socketServer3.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootLogger=DEBUG, A -log4j.Logger.org.apache.log4j.test.ShortSocketServer=WARN -log4j.Logger.org.apache.log4j.net.SocketNode=WARN -log4j.appender.A=org.apache.log4j.FileAppender -log4j.appender.A.file=output/temp -log4j.appender.A.Append=false -log4j.appender.A.layout=org.apache.log4j.PatternLayout -log4j.appender.A.layout.ConversionPattern=%5p %x [%t] %C (%F:%L) %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.net.ShortSocketServer=INFO \ No newline at end of file diff --git a/tests/input/net/socketServer4.properties b/tests/input/net/socketServer4.properties deleted file mode 100644 index cb56cfe131..0000000000 --- a/tests/input/net/socketServer4.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootLogger=DEBUG, A -log4j.Logger.org.apache.log4j.test.ShortSocketServer=WARN -log4j.Logger.org.apache.log4j.net.SocketNode=WARN -log4j.appender.A=org.apache.log4j.FileAppender -log4j.appender.A.file=output/temp -log4j.appender.A.Append=false -log4j.appender.A.layout=org.apache.log4j.PatternLayout -log4j.appender.A.layout.ConversionPattern=%5p %x %X{key1}%X{key4} [%t] %c{1} - %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.net.ShortSocketServer=INFO \ No newline at end of file diff --git a/tests/input/net/socketServer5.properties b/tests/input/net/socketServer5.properties deleted file mode 100644 index bb9e41b6a6..0000000000 --- a/tests/input/net/socketServer5.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootLogger=DEBUG, A -log4j.Logger.org.apache.log4j.test.ShortSocketServer=WARN -log4j.Logger.org.apache.log4j.net.SocketNode=WARN -log4j.appender.A=org.apache.log4j.FileAppender -log4j.appender.A.file=output/temp -log4j.appender.A.Append=false -log4j.appender.A.layout=org.apache.log4j.PatternLayout -log4j.appender.A.layout.ConversionPattern=%5p %x %X{key1}%X{key5} [%t] %c{1} - %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.net.ShortSocketServer=INFO \ No newline at end of file diff --git a/tests/input/net/socketServer6.properties b/tests/input/net/socketServer6.properties deleted file mode 100644 index 5e66dfd6e9..0000000000 --- a/tests/input/net/socketServer6.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootLogger=DEBUG, A -log4j.Logger.org.apache.log4j.test.ShortSocketServer=WARN -log4j.Logger.org.apache.log4j.net.SocketNode=WARN -log4j.appender.A=org.apache.log4j.FileAppender -log4j.appender.A.file=output/temp -log4j.appender.A.Append=false -log4j.appender.A.layout=org.apache.log4j.PatternLayout -log4j.appender.A.layout.ConversionPattern=%5p %x %X{hostID} %X{key6} [%t] %c{1} - %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.net.ShortSocketServer=INFO \ No newline at end of file diff --git a/tests/input/net/socketServer7.properties b/tests/input/net/socketServer7.properties deleted file mode 100644 index a5dac81bd3..0000000000 --- a/tests/input/net/socketServer7.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootLogger=DEBUG, A -log4j.Logger.org.apache.log4j.test.ShortSocketServer=WARN -log4j.Logger.org.apache.log4j.net.SocketNode=WARN -log4j.appender.A=org.apache.log4j.FileAppender -log4j.appender.A.file=output/temp -log4j.appender.A.Append=false -log4j.appender.A.layout=org.apache.log4j.PatternLayout -log4j.appender.A.layout.ConversionPattern=%5p %x %X{hostID} %X{key7} [%t] %c{1} - %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.net.ShortSocketServer=INFO \ No newline at end of file diff --git a/tests/input/net/socketServer8.properties b/tests/input/net/socketServer8.properties deleted file mode 100644 index 020b4ec725..0000000000 --- a/tests/input/net/socketServer8.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootLogger=DEBUG, A -log4j.Logger.org.apache.log4j.test.ShortSocketServer=WARN -log4j.Logger.org.apache.log4j.net.SocketNode=WARN -log4j.appender.A=org.apache.log4j.FileAppender -log4j.appender.A.file=output/temp -log4j.appender.A.Append=false -log4j.appender.A.layout=org.apache.log4j.PatternLayout -log4j.appender.A.layout.ConversionPattern=%5p %x %X{hostID} %X{key8} [%t] %c{1} - %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.net.ShortSocketServer=INFO \ No newline at end of file diff --git a/tests/input/pattern/enhancedPatternLayout.mdc.1.properties b/tests/input/pattern/enhancedPatternLayout.mdc.1.properties new file mode 100644 index 0000000000..dc6055ab08 --- /dev/null +++ b/tests/input/pattern/enhancedPatternLayout.mdc.1.properties @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootCategory=DEBUG, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.EnhancedPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%-5p - %m %X%n + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/enhancedPatternLayout1.properties b/tests/input/pattern/enhancedPatternLayout1.properties new file mode 100644 index 0000000000..7d73b79951 --- /dev/null +++ b/tests/input/pattern/enhancedPatternLayout1.properties @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootLogger=DEBUG, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.file=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.EnhancedPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%-5p - %m%n + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/enhancedPatternLayout10.properties b/tests/input/pattern/enhancedPatternLayout10.properties new file mode 100644 index 0000000000..cf62885b1a --- /dev/null +++ b/tests/input/pattern/enhancedPatternLayout10.properties @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootCategory=DEBUG, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append= false +log4j.appender.testAppender.layout=org.apache.log4j.EnhancedPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=[%t] %-5p %l: %m%n + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/enhancedPatternLayout11.properties b/tests/input/pattern/enhancedPatternLayout11.properties new file mode 100644 index 0000000000..02b7798664 --- /dev/null +++ b/tests/input/pattern/enhancedPatternLayout11.properties @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootCategory=DEBUG, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.EnhancedPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%-5p [%t] %c{2}: %m%n + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/enhancedPatternLayout12.properties b/tests/input/pattern/enhancedPatternLayout12.properties new file mode 100644 index 0000000000..3c2677952a --- /dev/null +++ b/tests/input/pattern/enhancedPatternLayout12.properties @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootCategory=DEBUG, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.EnhancedPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=[%t] %-5p %C.%M(%F:%L): %m%n + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/enhancedPatternLayout13.properties b/tests/input/pattern/enhancedPatternLayout13.properties new file mode 100644 index 0000000000..f7cadbe5dd --- /dev/null +++ b/tests/input/pattern/enhancedPatternLayout13.properties @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootCategory=DEBUG, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.EnhancedPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=[%t] %-5p %C{3}.%M(%F:%L): %m%n + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/enhancedPatternLayout14.properties b/tests/input/pattern/enhancedPatternLayout14.properties new file mode 100644 index 0000000000..cbb8b694db --- /dev/null +++ b/tests/input/pattern/enhancedPatternLayout14.properties @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootCategory=DEBUG, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.EnhancedPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%-5p [%t] %c{1.}: %m%n + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/enhancedPatternLayout15.properties b/tests/input/pattern/enhancedPatternLayout15.properties new file mode 100644 index 0000000000..fc98586dde --- /dev/null +++ b/tests/input/pattern/enhancedPatternLayout15.properties @@ -0,0 +1,26 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootCategory=TRACE, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.EnhancedMyPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%5p %-4# - %m%n + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO + diff --git a/tests/input/pattern/enhancedPatternLayout16.properties b/tests/input/pattern/enhancedPatternLayout16.properties new file mode 100644 index 0000000000..b4ad3a2a3d --- /dev/null +++ b/tests/input/pattern/enhancedPatternLayout16.properties @@ -0,0 +1,27 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +log4j.rootCategory=TRACE, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/patternLayout16.log +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.EnhancedPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}{GMT}Z %d{yyyy-MM-dd HH:mm:ss}{GMT-6}-0600 - %m%n + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO + diff --git a/tests/input/pattern/enhancedPatternLayout2.properties b/tests/input/pattern/enhancedPatternLayout2.properties new file mode 100644 index 0000000000..5858647d4e --- /dev/null +++ b/tests/input/pattern/enhancedPatternLayout2.properties @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootCategory=DEBUG, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append= false +log4j.appender.testAppender.layout=org.apache.log4j.EnhancedPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %.16c - %m%n + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/enhancedPatternLayout3.properties b/tests/input/pattern/enhancedPatternLayout3.properties new file mode 100644 index 0000000000..72b3ab176e --- /dev/null +++ b/tests/input/pattern/enhancedPatternLayout3.properties @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootCategory=DEBUG, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.EnhancedPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %.16c - %m%n + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/enhancedPatternLayout4.properties b/tests/input/pattern/enhancedPatternLayout4.properties new file mode 100644 index 0000000000..0438cc9409 --- /dev/null +++ b/tests/input/pattern/enhancedPatternLayout4.properties @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootCategory=DEBUG, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.EnhancedPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%d{DATE} [%t] %-5p %.16c - %m%n + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/enhancedPatternLayout5.properties b/tests/input/pattern/enhancedPatternLayout5.properties new file mode 100644 index 0000000000..24f30e4eca --- /dev/null +++ b/tests/input/pattern/enhancedPatternLayout5.properties @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootCategory=DEBUG, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.EnhancedPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss,SSS} [%t] %-5p %.16c - %m%n + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/enhancedPatternLayout6.properties b/tests/input/pattern/enhancedPatternLayout6.properties new file mode 100644 index 0000000000..8284edd3de --- /dev/null +++ b/tests/input/pattern/enhancedPatternLayout6.properties @@ -0,0 +1,26 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootCategory=DEBUG, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.EnhancedPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%d{ABSOLUTE} [%t] %-5p %.16c - %m%n + + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/enhancedPatternLayout7.properties b/tests/input/pattern/enhancedPatternLayout7.properties new file mode 100644 index 0000000000..eed2a34385 --- /dev/null +++ b/tests/input/pattern/enhancedPatternLayout7.properties @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootCategory=DEBUG, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.EnhancedPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%t] %-5p %.16c - %m%n + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/enhancedPatternLayout8.properties b/tests/input/pattern/enhancedPatternLayout8.properties new file mode 100644 index 0000000000..22a8eaf718 --- /dev/null +++ b/tests/input/pattern/enhancedPatternLayout8.properties @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootCategory=DEBUG, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.EnhancedPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%r [%t] %-5p %.16c - %m%n + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/enhancedPatternLayout9.properties b/tests/input/pattern/enhancedPatternLayout9.properties new file mode 100644 index 0000000000..705d62c0f3 --- /dev/null +++ b/tests/input/pattern/enhancedPatternLayout9.properties @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootCategory=DEBUG, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.EnhancedPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=[%t] %-5p %.16c : %m%n + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/patternLayout.mdc.1.properties b/tests/input/pattern/patternLayout.mdc.1.properties deleted file mode 100644 index 029b703bae..0000000000 --- a/tests/input/pattern/patternLayout.mdc.1.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootCategory=DEBUG, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.File=output/temp -log4j.appender.testAppender.Append=false -log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.testAppender.layout.ConversionPattern=%-5p - %m %X%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/patternLayout1.properties b/tests/input/pattern/patternLayout1.properties deleted file mode 100644 index 682b9f3156..0000000000 --- a/tests/input/pattern/patternLayout1.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootLogger=DEBUG, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.file=output/temp -log4j.appender.testAppender.Append=false -log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.testAppender.layout.ConversionPattern=%-5p - %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/patternLayout10.properties b/tests/input/pattern/patternLayout10.properties deleted file mode 100644 index 35a2f70046..0000000000 --- a/tests/input/pattern/patternLayout10.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootCategory=DEBUG, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.File= output/temp -log4j.appender.testAppender.Append= false -log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.testAppender.layout.ConversionPattern=[%t] %-5p %l: %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/patternLayout11.properties b/tests/input/pattern/patternLayout11.properties deleted file mode 100644 index c9dd393a22..0000000000 --- a/tests/input/pattern/patternLayout11.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootCategory=DEBUG, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.File=output/temp -log4j.appender.testAppender.Append=false -log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.testAppender.layout.ConversionPattern=%-5p [%t] %c{2}: %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/patternLayout12.properties b/tests/input/pattern/patternLayout12.properties deleted file mode 100644 index e0f9817f58..0000000000 --- a/tests/input/pattern/patternLayout12.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootCategory=DEBUG, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.File=output/temp -log4j.appender.testAppender.Append=false -log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.testAppender.layout.ConversionPattern=[%t] %-5p %C.%M(%F:%L): %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/patternLayout13.properties b/tests/input/pattern/patternLayout13.properties deleted file mode 100644 index 9d15468844..0000000000 --- a/tests/input/pattern/patternLayout13.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootCategory=DEBUG, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.File= output/temp -log4j.appender.testAppender.Append=false -log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.testAppender.layout.ConversionPattern=[%t] %-5p %C{3}.%M(%F:%L): %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/patternLayout14.properties b/tests/input/pattern/patternLayout14.properties deleted file mode 100644 index 1fc7af5f53..0000000000 --- a/tests/input/pattern/patternLayout14.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootCategory=DEBUG, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.File=output/temp -log4j.appender.testAppender.Append=false -log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.testAppender.layout.ConversionPattern=%-5p [%t] %c{1.}: %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/patternLayout15.properties b/tests/input/pattern/patternLayout15.properties deleted file mode 100644 index 563e15ef3f..0000000000 --- a/tests/input/pattern/patternLayout15.properties +++ /dev/null @@ -1,12 +0,0 @@ -log4j.rootCategory=TRACE, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.File= output/temp -log4j.appender.testAppender.Append=false -log4j.appender.testAppender.layout=org.apache.log4j.MyPatternLayout -log4j.appender.testAppender.layout.ConversionPattern=%5p %-4# - %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO - diff --git a/tests/input/pattern/patternLayout16.properties b/tests/input/pattern/patternLayout16.properties deleted file mode 100644 index 2f983ceded..0000000000 --- a/tests/input/pattern/patternLayout16.properties +++ /dev/null @@ -1,27 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -log4j.rootCategory=TRACE, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.File=output/patternLayout16.log -log4j.appender.testAppender.Append=false -log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.testAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}{GMT}Z %d{yyyy-MM-dd HH:mm:ss}{GMT-6}-0600 - %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO - diff --git a/tests/input/pattern/patternLayout2.properties b/tests/input/pattern/patternLayout2.properties deleted file mode 100644 index ca68bcea9d..0000000000 --- a/tests/input/pattern/patternLayout2.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootCategory=DEBUG, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.File=output/temp -log4j.appender.testAppender.Append= false -log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.testAppender.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %.16c - %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/patternLayout3.properties b/tests/input/pattern/patternLayout3.properties deleted file mode 100644 index 2d357a33b8..0000000000 --- a/tests/input/pattern/patternLayout3.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootCategory=DEBUG, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.File=output/temp -log4j.appender.testAppender.Append=false -log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.testAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %.16c - %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/patternLayout4.properties b/tests/input/pattern/patternLayout4.properties deleted file mode 100644 index cb86146d45..0000000000 --- a/tests/input/pattern/patternLayout4.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootCategory=DEBUG, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.File=output/temp -log4j.appender.testAppender.Append=false -log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.testAppender.layout.ConversionPattern=%d{DATE} [%t] %-5p %.16c - %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/patternLayout5.properties b/tests/input/pattern/patternLayout5.properties deleted file mode 100644 index a2736d1031..0000000000 --- a/tests/input/pattern/patternLayout5.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootCategory=DEBUG, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.File=output/temp -log4j.appender.testAppender.Append=false -log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.testAppender.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss,SSS} [%t] %-5p %.16c - %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/patternLayout6.properties b/tests/input/pattern/patternLayout6.properties deleted file mode 100644 index 7fa11c26e4..0000000000 --- a/tests/input/pattern/patternLayout6.properties +++ /dev/null @@ -1,12 +0,0 @@ -log4j.rootCategory=DEBUG, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.File=output/temp -log4j.appender.testAppender.Append=false -log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.testAppender.layout.ConversionPattern=%d{ABSOLUTE} [%t] %-5p %.16c - %m%n - - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/patternLayout7.properties b/tests/input/pattern/patternLayout7.properties deleted file mode 100644 index 12682f407a..0000000000 --- a/tests/input/pattern/patternLayout7.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootCategory=DEBUG, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.File=output/temp -log4j.appender.testAppender.Append=false -log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.testAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%t] %-5p %.16c - %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/patternLayout8.properties b/tests/input/pattern/patternLayout8.properties deleted file mode 100644 index 61efe8a1ce..0000000000 --- a/tests/input/pattern/patternLayout8.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootCategory=DEBUG, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.File=output/temp -log4j.appender.testAppender.Append=false -log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.testAppender.layout.ConversionPattern=%r [%t] %-5p %.16c - %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/pattern/patternLayout9.properties b/tests/input/pattern/patternLayout9.properties deleted file mode 100644 index e37fd7f052..0000000000 --- a/tests/input/pattern/patternLayout9.properties +++ /dev/null @@ -1,11 +0,0 @@ -log4j.rootCategory=DEBUG, testAppender -log4j.appender.testAppender=org.apache.log4j.FileAppender -log4j.appender.testAppender.File=output/temp -log4j.appender.testAppender.Append=false -log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.testAppender.layout.ConversionPattern=[%t] %-5p %.16c : %m%n - -# Prevent internal log4j DEBUG messages from polluting the output. -log4j.logger.org.apache.log4j.PropertyConfigurator=INFO -log4j.logger.org.apache.log4j.config.PropertySetter=INFO -log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/patternLayout.mdc.1.properties b/tests/input/patternLayout.mdc.1.properties new file mode 100644 index 0000000000..d3a5439b2e --- /dev/null +++ b/tests/input/patternLayout.mdc.1.properties @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootCategory=DEBUG, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%-5p - %m %X%n + +# Prevent internal log4j DEBUG messages from polluting the output. +log4j.logger.org.apache.log4j.PropertyConfigurator=INFO +log4j.logger.org.apache.log4j.config.PropertySetter=INFO +log4j.logger.org.apache.log4j.FileAppender=INFO diff --git a/tests/input/patternLayout1.properties b/tests/input/patternLayout1.properties new file mode 100644 index 0000000000..634c19542e --- /dev/null +++ b/tests/input/patternLayout1.properties @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.rootCategory=TRACE, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%-5p - %m%n \ No newline at end of file diff --git a/tests/input/patternLayout10.properties b/tests/input/patternLayout10.properties new file mode 100644 index 0000000000..117969d39f --- /dev/null +++ b/tests/input/patternLayout10.properties @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.rootCategory=TRACE, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File= output/temp +log4j.appender.testAppender.Append= false +log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.testAppender.layout.ConversionPattern=[%t] %-5p %l: %m%n \ No newline at end of file diff --git a/tests/input/patternLayout11.properties b/tests/input/patternLayout11.properties new file mode 100644 index 0000000000..a94325a998 --- /dev/null +++ b/tests/input/patternLayout11.properties @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.rootCategory=TRACE, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%-5p [%t] %c{2}: %m%n \ No newline at end of file diff --git a/tests/input/patternLayout12.properties b/tests/input/patternLayout12.properties new file mode 100644 index 0000000000..bc0f3f0f05 --- /dev/null +++ b/tests/input/patternLayout12.properties @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.rootCategory=TRACE, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.testAppender.layout.ConversionPattern=[%t] %-5p %C.%M(%F:%L): %m%n \ No newline at end of file diff --git a/tests/input/patternLayout13.properties b/tests/input/patternLayout13.properties new file mode 100644 index 0000000000..b965dfb36c --- /dev/null +++ b/tests/input/patternLayout13.properties @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.rootCategory=TRACE, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File= output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.testAppender.layout.ConversionPattern=[%t] %-5p %C{3}.%M(%F:%L): %m%n \ No newline at end of file diff --git a/tests/input/patternLayout14.properties b/tests/input/patternLayout14.properties new file mode 100644 index 0000000000..f0cf51fb9b --- /dev/null +++ b/tests/input/patternLayout14.properties @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.rootCategory=TRACE, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File= output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.MyPatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%5p %-4# - %m%n diff --git a/tests/input/patternLayout2.properties b/tests/input/patternLayout2.properties new file mode 100644 index 0000000000..951ca9513a --- /dev/null +++ b/tests/input/patternLayout2.properties @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.rootCategory=TRACE, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append= false +log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %.16c - %m%n diff --git a/tests/input/patternLayout3.properties b/tests/input/patternLayout3.properties new file mode 100644 index 0000000000..e9846c79f9 --- /dev/null +++ b/tests/input/patternLayout3.properties @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.rootCategory=TRACE, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %.16c - %m%n \ No newline at end of file diff --git a/tests/input/patternLayout4.properties b/tests/input/patternLayout4.properties new file mode 100644 index 0000000000..6a2e442146 --- /dev/null +++ b/tests/input/patternLayout4.properties @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.rootCategory=TRACE, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%d{DATE} [%t] %-5p %.16c - %m%n \ No newline at end of file diff --git a/tests/input/patternLayout5.properties b/tests/input/patternLayout5.properties new file mode 100644 index 0000000000..1acfaf8320 --- /dev/null +++ b/tests/input/patternLayout5.properties @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.rootCategory=TRACE, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss,SSS} [%t] %-5p %.16c - %m%n \ No newline at end of file diff --git a/tests/input/patternLayout6.properties b/tests/input/patternLayout6.properties new file mode 100644 index 0000000000..2eb6dabc4d --- /dev/null +++ b/tests/input/patternLayout6.properties @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.rootCategory=TRACE, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%d{ABSOLUTE} [%t] %-5p %.16c - %m%n \ No newline at end of file diff --git a/tests/input/patternLayout7.properties b/tests/input/patternLayout7.properties new file mode 100644 index 0000000000..921d5520b8 --- /dev/null +++ b/tests/input/patternLayout7.properties @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.rootCategory=TRACE, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%t] %-5p %.16c - %m%n diff --git a/tests/input/patternLayout8.properties b/tests/input/patternLayout8.properties new file mode 100644 index 0000000000..bf56fab098 --- /dev/null +++ b/tests/input/patternLayout8.properties @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.rootCategory=TRACE, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.testAppender.layout.ConversionPattern=%r [%t] %-5p %.16c - %m%n \ No newline at end of file diff --git a/tests/input/patternLayout9.properties b/tests/input/patternLayout9.properties new file mode 100644 index 0000000000..aa468785f5 --- /dev/null +++ b/tests/input/patternLayout9.properties @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +log4j.rootCategory=TRACE, testAppender +log4j.appender.testAppender=org.apache.log4j.FileAppender +log4j.appender.testAppender.File=output/temp +log4j.appender.testAppender.Append=false +log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.testAppender.layout.ConversionPattern=[%t] %-5p %.16c : %m%n \ No newline at end of file diff --git a/tests/input/performance/file-bufferedio.xml b/tests/input/performance/file-bufferedio.xml deleted file mode 100644 index fe0a96d5f2..0000000000 --- a/tests/input/performance/file-bufferedio.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/performance/file-noflush.xml b/tests/input/performance/file-noflush.xml deleted file mode 100644 index 35d22013cd..0000000000 --- a/tests/input/performance/file-noflush.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/performance/file.xml b/tests/input/performance/file.xml deleted file mode 100644 index f997fd050c..0000000000 --- a/tests/input/performance/file.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/performance/null-appender-info.xml b/tests/input/performance/null-appender-info.xml deleted file mode 100644 index af0bdc138c..0000000000 --- a/tests/input/performance/null-appender-info.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/performance/null-appender.xml b/tests/input/performance/null-appender.xml deleted file mode 100644 index acfcd662b6..0000000000 --- a/tests/input/performance/null-appender.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/tests/input/performance/telnet.xml b/tests/input/performance/telnet.xml deleted file mode 100644 index 6a2964ea50..0000000000 --- a/tests/input/performance/telnet.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/tests/input/rolling/filter1.xml b/tests/input/rolling/filter1.xml deleted file mode 100644 index 7c5108f00a..0000000000 --- a/tests/input/rolling/filter1.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/input/rolling/time1.xml b/tests/input/rolling/time1.xml deleted file mode 100644 index 766007adc4..0000000000 --- a/tests/input/rolling/time1.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/input/socketServer1.properties b/tests/input/socketServer1.properties new file mode 100644 index 0000000000..573524b6f9 --- /dev/null +++ b/tests/input/socketServer1.properties @@ -0,0 +1,23 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootLogger=TRACE, A +log4j.logger.org.apache.log4j.test.ShortSocketServer=WARN +log4j.logger.org.apache.log4j.net.SocketNode=WARN +log4j.appender.A=org.apache.log4j.FileAppender +log4j.appender.A.file=output/temp +log4j.appender.A.Append=false +log4j.appender.A.layout=org.apache.log4j.PatternLayout +log4j.appender.A.layout.ConversionPattern=%5p %x [%t] %c %m%n + diff --git a/tests/input/socketServer2.properties b/tests/input/socketServer2.properties new file mode 100644 index 0000000000..aafd7afba5 --- /dev/null +++ b/tests/input/socketServer2.properties @@ -0,0 +1,23 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootLogger=TRACE, A +log4j.logger.org.apache.log4j.test.ShortSocketServer=WARN +log4j.logger.org.apache.log4j.net.SocketNode=WARN +log4j.appender.A=org.apache.log4j.FileAppender +log4j.appender.A.file=output/temp +log4j.appender.A.Append=false +log4j.appender.A.layout=org.apache.log4j.PatternLayout +log4j.appender.A.layout.ConversionPattern=%5p %x [%t] %C (%F:%L) %m%n + diff --git a/tests/input/socketServer3.properties b/tests/input/socketServer3.properties new file mode 100644 index 0000000000..7ddb85c6f1 --- /dev/null +++ b/tests/input/socketServer3.properties @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootLogger=TRACE, A +log4j.Logger.org.apache.log4j.test.ShortSocketServer=WARN +log4j.Logger.org.apache.log4j.net.SocketNode=WARN +log4j.appender.A=org.apache.log4j.FileAppender +log4j.appender.A.file=output/temp +log4j.appender.A.Append=false +log4j.appender.A.layout=org.apache.log4j.PatternLayout +log4j.appender.A.layout.ConversionPattern=%5p %x [%t] %C (%F:%L) %m%n diff --git a/tests/input/socketServer4.properties b/tests/input/socketServer4.properties new file mode 100644 index 0000000000..c00fd65b27 --- /dev/null +++ b/tests/input/socketServer4.properties @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootLogger=TRACE, A +log4j.Logger.org.apache.log4j.test.ShortSocketServer=WARN +log4j.Logger.org.apache.log4j.net.SocketNode=WARN +log4j.appender.A=org.apache.log4j.FileAppender +log4j.appender.A.file=output/temp +log4j.appender.A.Append=false +log4j.appender.A.layout=org.apache.log4j.PatternLayout +log4j.appender.A.layout.ConversionPattern=%5p %x %X{key1}%X{key4} [%t] %c{1} - %m%n diff --git a/tests/input/socketServer5.properties b/tests/input/socketServer5.properties new file mode 100644 index 0000000000..d2d03ce8b6 --- /dev/null +++ b/tests/input/socketServer5.properties @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootLogger=TRACE, A +log4j.Logger.org.apache.log4j.test.ShortSocketServer=WARN +log4j.Logger.org.apache.log4j.net.SocketNode=WARN +log4j.appender.A=org.apache.log4j.FileAppender +log4j.appender.A.file=output/temp +log4j.appender.A.Append=false +log4j.appender.A.layout=org.apache.log4j.PatternLayout +log4j.appender.A.layout.ConversionPattern=%5p %x %X{key1}%X{key5} [%t] %c{1} - %m%n diff --git a/tests/input/socketServer6.properties b/tests/input/socketServer6.properties new file mode 100644 index 0000000000..19a817c40c --- /dev/null +++ b/tests/input/socketServer6.properties @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootLogger=TRACE, A +log4j.Logger.org.apache.log4j.test.ShortSocketServer=WARN +log4j.Logger.org.apache.log4j.net.SocketNode=WARN +log4j.appender.A=org.apache.log4j.FileAppender +log4j.appender.A.file=output/temp +log4j.appender.A.Append=false +log4j.appender.A.layout=org.apache.log4j.PatternLayout +log4j.appender.A.layout.ConversionPattern=%5p %x %X{hostID} %X{key6} [%t] %c{1} - %m%n diff --git a/tests/input/socketServer7.properties b/tests/input/socketServer7.properties new file mode 100644 index 0000000000..742eceb479 --- /dev/null +++ b/tests/input/socketServer7.properties @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootLogger=TRACE, A +log4j.Logger.org.apache.log4j.test.ShortSocketServer=WARN +log4j.Logger.org.apache.log4j.net.SocketNode=WARN +log4j.appender.A=org.apache.log4j.FileAppender +log4j.appender.A.file=output/temp +log4j.appender.A.Append=false +log4j.appender.A.layout=org.apache.log4j.PatternLayout +log4j.appender.A.layout.ConversionPattern=%5p %x %X{hostID} %X{key7} [%t] %c{1} - %m%n diff --git a/tests/input/socketServer8.properties b/tests/input/socketServer8.properties new file mode 100644 index 0000000000..fa31a08422 --- /dev/null +++ b/tests/input/socketServer8.properties @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +log4j.rootLogger=TRACE, A +log4j.Logger.org.apache.log4j.test.ShortSocketServer=WARN +log4j.Logger.org.apache.log4j.net.SocketNode=WARN +log4j.appender.A=org.apache.log4j.FileAppender +log4j.appender.A.file=output/temp +log4j.appender.A.Append=false +log4j.appender.A.layout=org.apache.log4j.PatternLayout +log4j.appender.A.layout.ConversionPattern=%5p %x %X{hostID} %X{key8} [%t] %c{1} - %m%n diff --git a/tests/input/ugli/basic.xml b/tests/input/ugli/basic.xml deleted file mode 100644 index 7112e1872a..0000000000 --- a/tests/input/ugli/basic.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/tests/input/watchdog/watchdog.FileWatchdog.test1_1.xml b/tests/input/watchdog/watchdog.FileWatchdog.test1_1.xml deleted file mode 100644 index 5943091e58..0000000000 --- a/tests/input/watchdog/watchdog.FileWatchdog.test1_1.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/watchdog/watchdog.FileWatchdog.test1_2.xml b/tests/input/watchdog/watchdog.FileWatchdog.test1_2.xml deleted file mode 100644 index 78b3f51f09..0000000000 --- a/tests/input/watchdog/watchdog.FileWatchdog.test1_2.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/tests/input/watchdog/watchdog.FileWatchdog.test2_1.properties b/tests/input/watchdog/watchdog.FileWatchdog.test2_1.properties deleted file mode 100644 index 56b3a16b69..0000000000 --- a/tests/input/watchdog/watchdog.FileWatchdog.test2_1.properties +++ /dev/null @@ -1,20 +0,0 @@ -log4j.debug=TRUE -log4j.threshold=ON - -log4j.rootLogger=DEBUG,A2 - -log4j.appender.A1=org.apache.log4j.FileAppender -log4j.appender.A1.File=output/watchdog.FileWatchdog.test2.txt -log4j.appender.A1.Append=false -log4j.appender.A1.layout=org.apache.log4j.PatternLayout -log4j.appender.A1.layout.ConversionPattern=%p - %m%n - -log4j.appender.A2=org.apache.log4j.ConsoleAppender -log4j.appender.A2.layout=org.apache.log4j.PatternLayout -log4j.appender.A2.layout.ConversionPattern=%d{ABSOLUTE} - TEST2_1 - %c{1} [%p] - %m%n - -#log4j.logger.org.apache.log4j=WARN -log4j.logger.test.FileWatchdogTestCase=DEBUG,A1 -log4j.logger.org.apache.log4j.watchdog.FileWatchdogTestCase=DEBUG -log4j.logger.org.apache.log4j=INFO -log4j.logger.org.apache.log4j.watchdog=DEBUG diff --git a/tests/input/watchdog/watchdog.FileWatchdog.test2_2.properties b/tests/input/watchdog/watchdog.FileWatchdog.test2_2.properties deleted file mode 100644 index 8fcc0d01c1..0000000000 --- a/tests/input/watchdog/watchdog.FileWatchdog.test2_2.properties +++ /dev/null @@ -1,15 +0,0 @@ -log4j.debug=TRUE -log4j.threshold=ON -log4j.rootLogger=DEBUG,A2 - -log4j.appender.A1=org.apache.log4j.FileAppender -log4j.appender.A1.File=output/watchdog.FileWatchdog.test2.txt -log4j.appender.A1.Append=true -log4j.appender.A1.layout=org.apache.log4j.PatternLayout -log4j.appender.A1.layout.ConversionPattern=%p - %m%n - -log4j.appender.A2=org.apache.log4j.ConsoleAppender -log4j.appender.A2.layout=org.apache.log4j.PatternLayout -log4j.appender.A2.layout.ConversionPattern=%d{ABSOLUTE} - TEST2_2 - %c{1} [%p] - %m%n - -log4j.logger.test.FileWatchdogTestCase=INFO,A1 diff --git a/tests/input/watchdog/watchdog.FileWatchdog.test3_1.xml b/tests/input/watchdog/watchdog.FileWatchdog.test3_1.xml deleted file mode 100755 index 06b9686f2f..0000000000 --- a/tests/input/watchdog/watchdog.FileWatchdog.test3_1.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/tests/input/watchdog/watchdog.FileWatchdog.test5_1.xml b/tests/input/watchdog/watchdog.FileWatchdog.test5_1.xml deleted file mode 100755 index 2ff7d50c2c..0000000000 --- a/tests/input/watchdog/watchdog.FileWatchdog.test5_1.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/watchdog/watchdog.FileWatchdog.test5_2.xml b/tests/input/watchdog/watchdog.FileWatchdog.test5_2.xml deleted file mode 100755 index 78b3f51f09..0000000000 --- a/tests/input/watchdog/watchdog.FileWatchdog.test5_2.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/tests/input/watchdog/watchdog.FileWatchdog.test6_1.properties b/tests/input/watchdog/watchdog.FileWatchdog.test6_1.properties deleted file mode 100755 index eb9ebc0cf7..0000000000 --- a/tests/input/watchdog/watchdog.FileWatchdog.test6_1.properties +++ /dev/null @@ -1,20 +0,0 @@ -log4j.debug=TRUE -log4j.threshold=ON - -log4j.rootLogger=DEBUG,A2 - -log4j.appender.A1=org.apache.log4j.FileAppender -log4j.appender.A1.File=output/watchdog.FileWatchdog.test6.txt -log4j.appender.A1.Append=false -log4j.appender.A1.layout=org.apache.log4j.PatternLayout -log4j.appender.A1.layout.ConversionPattern=%p - %m%n - -log4j.appender.A2=org.apache.log4j.ConsoleAppender -log4j.appender.A2.layout=org.apache.log4j.PatternLayout -log4j.appender.A2.layout.ConversionPattern=%d{ABSOLUTE} %c [%p] - %m%n - -#log4j.logger.org.apache.log4j=WARN -log4j.logger.test.FileWatchdogTestCase=DEBUG,A1 -log4j.logger.org.apache.log4j.watchdog.FileWatchdogTestCase=DEBUG -log4j.logger.org.apache.log4j=INFO -log4j.logger.org.apache.log4j.watchdog=DEBUG diff --git a/tests/input/watchdog/watchdog.FileWatchdog.test6_2.properties b/tests/input/watchdog/watchdog.FileWatchdog.test6_2.properties deleted file mode 100755 index 241a4998e7..0000000000 --- a/tests/input/watchdog/watchdog.FileWatchdog.test6_2.properties +++ /dev/null @@ -1,10 +0,0 @@ -log4j.debug=TRUE -log4j.threshold=ON - -log4j.appender.A1=org.apache.log4j.FileAppender -log4j.appender.A1.File=output/watchdog.FileWatchdog.test6.txt -log4j.appender.A1.Append=true -log4j.appender.A1.layout=org.apache.log4j.PatternLayout -log4j.appender.A1.layout.ConversionPattern=%p - %m%n - -log4j.logger.test.FileWatchdogTestCase=INFO,A1 diff --git a/tests/input/xml/DOMTest1.xml b/tests/input/xml/DOMTest1.xml deleted file mode 100644 index 930a03e333..0000000000 --- a/tests/input/xml/DOMTest1.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/xml/DOMTest2.xml b/tests/input/xml/DOMTest2.xml deleted file mode 100644 index 1c86565c1a..0000000000 --- a/tests/input/xml/DOMTest2.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/xml/DOMTest3.xml b/tests/input/xml/DOMTest3.xml deleted file mode 100644 index 6d07ef9563..0000000000 --- a/tests/input/xml/DOMTest3.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/xml/DOMTest4.xml b/tests/input/xml/DOMTest4.xml index 29ce949833..91aab08c41 100644 --- a/tests/input/xml/DOMTest4.xml +++ b/tests/input/xml/DOMTest4.xml @@ -3,6 +3,22 @@ ]> + &a1; @@ -16,12 +32,12 @@ - + - + diff --git a/tests/input/xml/DOMTest4_A1.xml b/tests/input/xml/DOMTest4_A1.xml index cd408ae08f..9b945e60aa 100644 --- a/tests/input/xml/DOMTest4_A1.xml +++ b/tests/input/xml/DOMTest4_A1.xml @@ -1,3 +1,19 @@ + diff --git a/tests/input/xml/DOMTest4_A2.xml b/tests/input/xml/DOMTest4_A2.xml index 302f0d88ab..e5e26c0248 100644 --- a/tests/input/xml/DOMTest4_A2.xml +++ b/tests/input/xml/DOMTest4_A2.xml @@ -1,3 +1,19 @@ + diff --git a/tests/input/xml/DOMTestCase1.xml b/tests/input/xml/DOMTestCase1.xml new file mode 100644 index 0000000000..fcd1a7ca59 --- /dev/null +++ b/tests/input/xml/DOMTestCase1.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/input/xml/SocketAppenderTestConfig.xml b/tests/input/xml/SocketAppenderTestConfig.xml new file mode 100644 index 0000000000..2930b7b258 --- /dev/null +++ b/tests/input/xml/SocketAppenderTestConfig.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/input/xml/categoryfactory1.xml b/tests/input/xml/categoryfactory1.xml new file mode 100644 index 0000000000..369e7c9474 --- /dev/null +++ b/tests/input/xml/categoryfactory1.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/input/xml/categoryfactory2.xml b/tests/input/xml/categoryfactory2.xml new file mode 100644 index 0000000000..146e5f2429 --- /dev/null +++ b/tests/input/xml/categoryfactory2.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/input/xml/customLevel1.xml b/tests/input/xml/customLevel1.xml index 14d60a1e02..5c798d2229 100644 --- a/tests/input/xml/customLevel1.xml +++ b/tests/input/xml/customLevel1.xml @@ -1,21 +1,33 @@ - + + + + - + - - - - - diff --git a/tests/input/xml/customLevel2.xml b/tests/input/xml/customLevel2.xml index 40a7d5234e..fdc0be1274 100644 --- a/tests/input/xml/customLevel2.xml +++ b/tests/input/xml/customLevel2.xml @@ -1,5 +1,21 @@ - + + @@ -12,18 +28,12 @@ value="%-5p %c{2} - %m\n"/> - + - - - - - - diff --git a/tests/input/xml/customLevel3.xml b/tests/input/xml/customLevel3.xml index 50c50a2d38..8e4b626856 100644 --- a/tests/input/xml/customLevel3.xml +++ b/tests/input/xml/customLevel3.xml @@ -1,5 +1,21 @@ - + + @@ -12,20 +28,15 @@ value="%-5p %c{2} - %m\n"/> - + - + - - - - - diff --git a/tests/input/xml/customLevel4.xml b/tests/input/xml/customLevel4.xml index e4097f770f..0ae0b75335 100644 --- a/tests/input/xml/customLevel4.xml +++ b/tests/input/xml/customLevel4.xml @@ -1,5 +1,21 @@ - + + @@ -13,12 +29,6 @@ - - - - - - diff --git a/tests/input/xml/customLogger1.xml b/tests/input/xml/customLogger1.xml index 0b3c4c5542..3a09151f88 100644 --- a/tests/input/xml/customLogger1.xml +++ b/tests/input/xml/customLogger1.xml @@ -1,5 +1,21 @@ - + + @@ -12,13 +28,7 @@ value="%-5p %c{2} - %m%n"/> - - - - - - - + diff --git a/tests/input/xml/customLogger2.xml b/tests/input/xml/customLogger2.xml index 0425622df2..3a33f5c44e 100644 --- a/tests/input/xml/customLogger2.xml +++ b/tests/input/xml/customLogger2.xml @@ -1,5 +1,21 @@ - + + @@ -12,21 +28,15 @@ value="%-5p %c{2} - %m%n"/> - + - + - - - - - - diff --git a/tests/input/xml/customLogger3.xml b/tests/input/xml/customLogger3.xml index 52a93d942a..000a1b9ce2 100644 --- a/tests/input/xml/customLogger3.xml +++ b/tests/input/xml/customLogger3.xml @@ -1,5 +1,21 @@ - + + @@ -13,12 +29,6 @@ - - - - - - diff --git a/tests/input/xml/defaultInit.xml b/tests/input/xml/defaultInit.xml index 956418fcb8..71bfbeac5c 100644 --- a/tests/input/xml/defaultInit.xml +++ b/tests/input/xml/defaultInit.xml @@ -1,5 +1,21 @@ - + + @@ -10,7 +26,7 @@ - + diff --git a/tests/input/xml/fallback1.xml b/tests/input/xml/fallback1.xml new file mode 100644 index 0000000000..5eb42c4f61 --- /dev/null +++ b/tests/input/xml/fallback1.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/input/xml/filters.LevelMatchFilter.test4.0.xml b/tests/input/xml/filters.LevelMatchFilter.test4.0.xml deleted file mode 100644 index 744827c5be..0000000000 --- a/tests/input/xml/filters.LevelMatchFilter.test4.0.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/xml/filters.LevelMatchFilter.test4.1.xml b/tests/input/xml/filters.LevelMatchFilter.test4.1.xml deleted file mode 100644 index 50cc23dee6..0000000000 --- a/tests/input/xml/filters.LevelMatchFilter.test4.1.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/xml/filters.LevelMatchFilter.test4.2.xml b/tests/input/xml/filters.LevelMatchFilter.test4.2.xml deleted file mode 100644 index 8ceee9109b..0000000000 --- a/tests/input/xml/filters.LevelMatchFilter.test4.2.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/xml/filters.LevelMatchFilter.test4.3.xml b/tests/input/xml/filters.LevelMatchFilter.test4.3.xml deleted file mode 100644 index e1b3058318..0000000000 --- a/tests/input/xml/filters.LevelMatchFilter.test4.3.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/xml/filters.LevelMatchFilter.test4.4.xml b/tests/input/xml/filters.LevelMatchFilter.test4.4.xml deleted file mode 100644 index 860c73d7f4..0000000000 --- a/tests/input/xml/filters.LevelMatchFilter.test4.4.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/input/xml/loggerFactory1.xml b/tests/input/xml/loggerFactory1.xml deleted file mode 100644 index 397a6f56da..0000000000 --- a/tests/input/xml/loggerFactory1.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/input/xml/loggerFactory2.xml b/tests/input/xml/loggerFactory2.xml deleted file mode 100644 index 8d6757c3cb..0000000000 --- a/tests/input/xml/loggerFactory2.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/input/xml/loggerfactory1.xml b/tests/input/xml/loggerfactory1.xml new file mode 100644 index 0000000000..c2514a7631 --- /dev/null +++ b/tests/input/xml/loggerfactory1.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/input/xml/plugins1.xml b/tests/input/xml/plugins1.xml deleted file mode 100644 index e148e4dd93..0000000000 --- a/tests/input/xml/plugins1.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - diff --git a/tests/input/xml/resetTest.xml b/tests/input/xml/resetTest.xml deleted file mode 100644 index 5571607adf..0000000000 --- a/tests/input/xml/resetTest.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/input/xml/smtpAppender1.xml b/tests/input/xml/smtpAppender1.xml new file mode 100644 index 0000000000..c1aebdf1ca --- /dev/null +++ b/tests/input/xml/smtpAppender1.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/input/xml/testReset.xml b/tests/input/xml/testReset.xml new file mode 100644 index 0000000000..185209e64b --- /dev/null +++ b/tests/input/xml/testReset.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + diff --git a/tests/input/xml/throwableRenderer1.xml b/tests/input/xml/throwableRenderer1.xml new file mode 100644 index 0000000000..2496870e0a --- /dev/null +++ b/tests/input/xml/throwableRenderer1.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/tests/input/xml/xinclude.xml b/tests/input/xml/xinclude.xml deleted file mode 100644 index ac7933b36e..0000000000 --- a/tests/input/xml/xinclude.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/input/xml/xinclude2.xml b/tests/input/xml/xinclude2.xml deleted file mode 100644 index 53df91b29b..0000000000 --- a/tests/input/xml/xinclude2.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/tests/integration/.cvsignore b/tests/integration/.cvsignore deleted file mode 100644 index f71328fe19..0000000000 --- a/tests/integration/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -server-side.log -build.properties diff --git a/tests/integration/README.txt b/tests/integration/README.txt deleted file mode 100644 index 458f91a336..0000000000 --- a/tests/integration/README.txt +++ /dev/null @@ -1,39 +0,0 @@ - -The tests in this directory (LOG4J_HOME/tests/integration/) test -log4j's integration with various Application Servers. Most of the -tests deal with the logging separation problem while others deal with -class loader issues. - -Unfortunately, we are currently unable to test web-applicatin -recycling with Cactus. - - -Prerequisites -============= - -You need a recent version of Ant. - -You need to place the following jar files in the ./lib/ directory. - - aspectjrt-1.1.1.jar - cactus-1.6.1.jar - cactus-ant-1.6.1.jar - commons-httpclient-2.0.jar - commons-logging-1.0.4.jar - -They are shipped by Cactus. - -You also need to place 'servletapi-2.3.jar' or equivalent in -./otherlib/ directory. This jar file also ships with Cactus. - -Modify the 'build.properties.sample' file as appropriate for your -environment and copy it as 'build.properties'. - -Make sure that you have a copy of Tomcat 5.0.x installed and -available. The 'tomcat5x.home' property should point to your Tomcat -5.0.x installation. - -Running the tests -================= - -There nothing more to it than invoking the 'ant test' command. diff --git a/tests/integration/build.properties.sample b/tests/integration/build.properties.sample deleted file mode 100644 index d0ee14d76f..0000000000 --- a/tests/integration/build.properties.sample +++ /dev/null @@ -1,5 +0,0 @@ - -# Copy an appropriately modified version of this file -# as 'build.properties' - -tomcat5x.home=/java/jakarta-tomcat-5.0.27 \ No newline at end of file diff --git a/tests/integration/build.xml b/tests/integration/build.xml deleted file mode 100644 index 4b90ecec01..0000000000 --- a/tests/integration/build.xml +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - These are the targets supported by this ANT build scpript: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Could not find the file - ${src.webapp.dir}/WEB-INF/classes/test-log4j.xml - Have you forgotten to adapt and rename the test-log4j.xml.sample file? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - tomcat5x.home variable not set - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/integration/client-log4j.xml b/tests/integration/client-log4j.xml deleted file mode 100644 index e49d7fa70a..0000000000 --- a/tests/integration/client-log4j.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/integration/client.properties b/tests/integration/client.properties deleted file mode 100644 index 73e7006301..0000000000 --- a/tests/integration/client.properties +++ /dev/null @@ -1,10 +0,0 @@ - -org.apache.commons.logging.Log = org.apache.commons.logging.impl.SimpleLog - - -# org.apache.commons.logging.Log = org.apache.commons.logging.impl.Log4JLogger - -# WORKS -# log4j.configuration=file:client-log4j.xml - - diff --git a/tests/integration/lib/.cvsignore b/tests/integration/lib/.cvsignore deleted file mode 100644 index 5fb815ae98..0000000000 --- a/tests/integration/lib/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -aspectjrt-1.1.1.jar -cactus-1.6.1.jar -cactus-ant-1.6.1.jar -commons-httpclient-2.0.jar -commons-logging-1.0.4.jar -httpunit-1.5.4.jar -junit-3.8.1.jar -log4j-1.3alpha-4.jar diff --git a/tests/integration/otherlib/.cvsignore b/tests/integration/otherlib/.cvsignore deleted file mode 100644 index 9411c53c0e..0000000000 --- a/tests/integration/otherlib/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -servletapi-2.3.jar diff --git a/tests/integration/server.properties b/tests/integration/server.properties deleted file mode 100644 index 01f79c46fe..0000000000 --- a/tests/integration/server.properties +++ /dev/null @@ -1 +0,0 @@ -log4j.repositorySelector=JNDI \ No newline at end of file diff --git a/tests/integration/src/java/SampleServlet.java b/tests/integration/src/java/SampleServlet.java deleted file mode 100644 index 11d08f510e..0000000000 --- a/tests/integration/src/java/SampleServlet.java +++ /dev/null @@ -1,50 +0,0 @@ -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; - -import org.apache.log4j.Logger; -import org.apache.log4j.Appender; -import org.apache.log4j.spi.LoggerRepository; - -public class SampleServlet extends HttpServlet { - - public void getLogger1() throws Exception { - - Logger logger = Logger.getLogger(this.getClass().getName()); - - LoggerRepository lr = logger.getLoggerRepository(); - if(lr == null) { - throw new Exception("The LR should not be null"); - } - - if(!"test".equals(lr.getName())) { - throw new Exception("The name of the returned LR should be 'test'"); - } - } - - /** - * This tests checks that an instance TestAppender named TEST could be - * instanciated. - * - *

    TestAppender is shipped part of the web-application. - * */ - public void webappShippedAppender() throws Exception { - - Logger logger = Logger.getLogger(this.getClass().getName()); - - LoggerRepository lr = logger.getLoggerRepository(); - - Logger root = lr.getRootLogger(); - Appender appender = root.getAppender("TEST"); - if(appender == null) { - throw new Exception("An appender named TEST should exist."); - } - } - - - public void exerciseSMPTPAppender() throws Exception { - Logger logger = Logger.getLogger(this.getClass().getName()); - logger.error("testing"); - } - -} - diff --git a/tests/integration/src/java/TestAppender.java b/tests/integration/src/java/TestAppender.java deleted file mode 100644 index 397cd81052..0000000000 --- a/tests/integration/src/java/TestAppender.java +++ /dev/null @@ -1,18 +0,0 @@ - -import org.apache.log4j.AppenderSkeleton; -import org.apache.log4j.spi.LoggingEvent; - - -public class TestAppender extends AppenderSkeleton { - - public void activateOptions() { - getLogger().debug("Activate options called for appender named {}.", - getName()); - } - - public void append(LoggingEvent event) { - } - - public void close() { - } -} diff --git a/tests/integration/src/webapp/WEB-INF/classes/.cvsignore b/tests/integration/src/webapp/WEB-INF/classes/.cvsignore deleted file mode 100644 index 3b50078db6..0000000000 --- a/tests/integration/src/webapp/WEB-INF/classes/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -test-log4j.xml diff --git a/tests/integration/src/webapp/WEB-INF/classes/test-log4j.xml.sample b/tests/integration/src/webapp/WEB-INF/classes/test-log4j.xml.sample deleted file mode 100644 index 4836a6ec52..0000000000 --- a/tests/integration/src/webapp/WEB-INF/classes/test-log4j.xml.sample +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/integration/src/webapp/WEB-INF/web.xml b/tests/integration/src/webapp/WEB-INF/web.xml deleted file mode 100644 index 573ae7ddda..0000000000 --- a/tests/integration/src/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - JNDI logging context for this app - log4j/context-name - test - java.lang.String - - - - URL for configuring log4j context - log4j/configuration-resource - test-log4j.xml - java.lang.String - - - - org.apache.log4j.selector.servlet.ContextDetachingSCL - - - diff --git a/tests/integration/target/.cvsignore b/tests/integration/target/.cvsignore deleted file mode 100644 index df03df6a04..0000000000 --- a/tests/integration/target/.cvsignore +++ /dev/null @@ -1,5 +0,0 @@ -classes -sample-servlet.war -test.war -report -test-appender.jar diff --git a/tests/integration/test/java/TestSampleServlet.java b/tests/integration/test/java/TestSampleServlet.java deleted file mode 100644 index ae913ebb04..0000000000 --- a/tests/integration/test/java/TestSampleServlet.java +++ /dev/null @@ -1,42 +0,0 @@ -import junit.framework.Test; -import junit.framework.TestSuite; - -import org.apache.cactus.ServletTestCase; -import org.apache.cactus.WebRequest; - -public class TestSampleServlet extends ServletTestCase { - public TestSampleServlet(String theName) { - super(theName); - } - - public static Test suite() { - return new TestSuite(TestSampleServlet.class); - } - - //public void beginSaveToSessionOK(WebRequest webRequest) { - //webRequest.addParameter("testparam", "it works!"); - //} - - //public void testSaveToSessionOK() { - //SampleServlet servlet = new SampleServlet(); - //servlet.saveToSession(request); - //assertEquals("it works!", session.getAttribute("testAttribute")); - //} - - public void testGetLogger1() throws Exception { - SampleServlet servlet = new SampleServlet(); - servlet.getLogger1(); - } - - public void testwebappShippedAppender() throws Exception { - SampleServlet servlet = new SampleServlet(); - servlet.webappShippedAppender(); - } - - public void testExerciseSMPTPAppender() throws Exception { - SampleServlet servlet = new SampleServlet(); - servlet.exerciseSMPTPAppender(); - - } - -} diff --git a/tests/lib/.cvsignore b/tests/lib/.cvsignore deleted file mode 100644 index 9624142747..0000000000 --- a/tests/lib/.cvsignore +++ /dev/null @@ -1,11 +0,0 @@ -fscontext.jar -hsqldb.jar -jasper-compiler.jar -jasper-runtime.jar -javax.servlet.jar -mysql-connector-java-3.0.12-production-bin.jar -org.mortbay.jetty.jar -org.mortbay.jetty.plus.jar -providerutil.jar -c3p0-0.8.4.5.jar -pg74jdbc3.jar diff --git a/src/log4j-coding-convention.xml b/tests/log4j-coding-convention.xml similarity index 100% rename from src/log4j-coding-convention.xml rename to tests/log4j-coding-convention.xml diff --git a/tests/performance.xml b/tests/performance.xml deleted file mode 100644 index c318881c95..0000000000 --- a/tests/performance.xml +++ /dev/null @@ -1,169 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - These are the targets supported by this ANT build scpript: - - all - run all performance tests - null - run performance tests using NullAppender - file - run performance tests using FileAppender - file-noflush - run performance tests using FileAppender without immediate flush - file-bufferedio - run performance tests using FileAppender without buffered IO - telnet - run performace tests with TelnetAppender - getLogger - run getLogger performance test - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/resources/L7D_en_US.properties b/tests/resources/L7D_en_US.properties index 4620e30e5f..c3c2802d52 100644 --- a/tests/resources/L7D_en_US.properties +++ b/tests/resources/L7D_en_US.properties @@ -1,3 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. test=This is the English, US test. hello_world=Hello world. msg1=This is test number {0} with string argument {1}. diff --git a/tests/resources/L7D_fr.properties b/tests/resources/L7D_fr.properties index 2e883c5c83..25b878aebc 100644 --- a/tests/resources/L7D_fr.properties +++ b/tests/resources/L7D_fr.properties @@ -1,3 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. test=Ceci est le test en francais pour la France. hello_world=Bonjour la France. msg1=Ceci est le test numero {0} contenant l''argument {1}. diff --git a/tests/resources/L7D_fr_CH.properties b/tests/resources/L7D_fr_CH.properties index 89293954d9..ba9b1ffbfc 100644 --- a/tests/resources/L7D_fr_CH.properties +++ b/tests/resources/L7D_fr_CH.properties @@ -1,2 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. test=Ceci est le test en francais pour la p'tite Suisse. hello world=Salut le monde. diff --git a/tests/resources/TestLogSFPatterns.properties b/tests/resources/TestLogSFPatterns.properties new file mode 100644 index 0000000000..e771863a53 --- /dev/null +++ b/tests/resources/TestLogSFPatterns.properties @@ -0,0 +1,24 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +Iteration0=Iteration {} +Hello1=Hello, World +Malformed=Hello, {. +Hello2=Hello, {}World +Hello3=Hello, {} +Hello4={}, {}. +Hello5={}{} {}. +Hello6={}{} {}{} diff --git a/tests/resources/history/GIL.logging b/tests/resources/history/GIL.logging deleted file mode 100644 index ed05dc986c..0000000000 --- a/tests/resources/history/GIL.logging +++ /dev/null @@ -1,41 +0,0 @@ -GIL is a AMD Duron running at 800 MHz running W2000 and Sun's JDK 1.3. - -NullAppender: - - 4 SimpleLayout - 4 PatternLayout "%p - %m%n" - 4 PatternLayout "%-5p - %m%n" - 10 TTCCLayout/RELATIVE - 10 PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - 10 PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - 10 PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - 9 PatternLayout "%r [%t] %-5p %c - %m%n" - 25 TTCCLayout/ISO8601 - 28 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 58 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - 1309 PatternLayout "%l - %m%n" - 1379 PatternLayout "%C.%M.%L - %m%n" - -FileAppender: - - 26 SimpleLayout - 28 PatternLayout "%p - %m%n" - 47 TTCC/RELATIVE - 46 PatternLayout "%r [%t] %-5p %c %x - %m%n" - 70 TTCCLayout/ISO8601 - 75 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 99 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - 1524 PatternLayout "%l - %m%n" - -FileAppender: (ImmediateFlush=false) - - 20 SimpleLayout - 21 PatternLayout "%p - %m%n" - 38 TTCC/RELATIVE - 38 PatternLayout "%r [%t] %-5p %c %x - %m%n" - 62 TTCCLayout/ISO8601 - 67 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 86 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - -Notice the small but noticable performance gain when forgoing -immediate flush. diff --git a/tests/resources/history/kal0.txt b/tests/resources/history/kal0.txt deleted file mode 100644 index b356398d29..0000000000 --- a/tests/resources/history/kal0.txt +++ /dev/null @@ -1,67 +0,0 @@ -KAL is an Intel Pentium 4 clocked at 2.53 GHz running XP and Sun's JDK 1.4.1. - -Results are in microseconds. - -NullAppender: - -NullAppender: - - 4.11 PatternLayout "%p - %m%n" - 4.11 PatternLayout "%-5p - %m%n" - 13.52 PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - 11.02 PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - 11.72 PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - 10.01 PatternLayout "%r [%t] %-5p %c - %m%n" - 18.53 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 18.83 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - 127.18 PatternLayout "%l - %m%n" - 142.61 PatternLayout "%C.%M.%L - %m%n" - -FileAppender: - - 10.82 PatternLayout "%p - %m%n" - 11.82 PatternLayout "%-5p - %m%n" - 20.53 PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - 19.03 PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - 19.63 PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - 17.53 PatternLayout "%r [%t] %-5p %c - %m%n" - 28.74 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 29.14 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - 162.13 PatternLayout "%l - %m%n" - 198.69 PatternLayout "%C.%M.%L - %m%n" - -FileAppender: (ImmediateFlush=false) - - 6.31 PatternLayout "%p - %m%n" - 6.01 PatternLayout "%-5p - %m%n" - 14.42 PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - 14.22 PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - 14.42 PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - 13.02 PatternLayout "%r [%t] %-5p %c - %m%n" - 23.13 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 23.53 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - 147.51 PatternLayout "%l - %m%n" - 166.04 PatternLayout "%C.%M.%L - %m%n" - -FileAppender: (BufferedIO=true) - - 5.81 PatternLayout "%p - %m%n" - 5.81 PatternLayout "%-5p - %m%n" - 14.12 PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - 14.22 PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - 13.92 PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - 12.82 PatternLayout "%r [%t] %-5p %c - %m%n" - 22.73 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 23.23 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - 149.73 PatternLayout "%l - %m%n" - 164.46 PatternLayout "%C.%M.%L - %m%n" - -Notice the small but noticable performance gain when -ImmediateFlush=false - -Note also that BufferedIO yeilds similar performance to the -ImmediateFlush case. - - - - diff --git a/tests/resources/history/kal1.txt b/tests/resources/history/kal1.txt deleted file mode 100644 index 9639a22b2e..0000000000 --- a/tests/resources/history/kal1.txt +++ /dev/null @@ -1,67 +0,0 @@ -KAL is an Intel Pentium 4 clocked at 2.53 GHz running XP and Sun's JDK 1.4.1. - -Results are in microseconds. - -Tests are based on new LocationInfo extraction code optimized for JDK -1.4 and later. Note the significant improvement in speed wrt to -location info extraction. - -NullAppender: - - 3.97 PatternLayout "%p - %m%n" - 3.87 PatternLayout "%-5p - %m%n" - 10.68 PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - 10.48 PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - 10.41 PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - 9.18 PatternLayout "%r [%t] %-5p %c - %m%n" - 17.92 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 17.92 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - 68.13 PatternLayout "%l - %m%n" - 75.67 PatternLayout "%C.%M.%L - %m%n" - -FileAppender: - - 10.41 PatternLayout "%p - %m%n" - 10.34 PatternLayout "%-5p - %m%n" - 22.16 PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - 18.39 PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - 18.72 PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - 17.42 PatternLayout "%r [%t] %-5p %c - %m%n" - 28.61 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 27.94 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - 87.69 PatternLayout "%l - %m%n" - 93.16 PatternLayout "%C.%M.%L - %m%n" - -FileAppender: (ImmediateFlush=false) - - 5.80 PatternLayout "%p - %m%n" - 5.87 PatternLayout "%-5p - %m%n" - 13.82 PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - 13.48 PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - 13.82 PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - 12.75 PatternLayout "%r [%t] %-5p %c - %m%n" - 23.03 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 22.46 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - 81.98 PatternLayout "%l - %m%n" - 88.12 PatternLayout "%C.%M.%L - %m%n" - -FileAppender: (BufferedIO=true) - - 5.74 PatternLayout "%p - %m%n" - 5.84 PatternLayout "%-5p - %m%n" - 13.85 PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - 13.61 PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - 13.62 PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - 12.18 PatternLayout "%r [%t] %-5p %c - %m%n" - 21.83 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 22.1] PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - 81.01 PatternLayout "%l - %m%n" - 87.79 PatternLayout "%C.%M.%L - %m%n" - - - -Notice the small but noticable performance gain when -ImmediateFlush=false - -Note also that BufferedIO yeilds similar performance to the -ImmediateFlush case. diff --git a/tests/resources/history/kal2.txt b/tests/resources/history/kal2.txt deleted file mode 100644 index a6490b83b0..0000000000 --- a/tests/resources/history/kal2.txt +++ /dev/null @@ -1,57 +0,0 @@ -KAL is an Intel Pentium 4 clocked at 2.53 GHz running XP and Sun's JDK 1.4.1. - -Results are in microseconds. - - -NullAppender: - - PatternLayout "%p - %m%n" - PatternLayout "%-5p - %m%n" - PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - PatternLayout "%r [%t] %-5p %c - %m%n" - PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - PatternLayout "%l - %m%n" - PatternLayout "%C.%M.%L - %m%n" - -FileAppender: - - PatternLayout "%p - %m%n" - PatternLayout "%-5p - %m%n" - PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - PatternLayout "%r [%t] %-5p %c - %m%n" - PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - PatternLayout "%l - %m%n" - PatternLayout "%C.%M.%L - %m%n" - -FileAppender: (ImmediateFlush=false) - - PatternLayout "%p - %m%n" - PatternLayout "%-5p - %m%n" - PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - PatternLayout "%r [%t] %-5p %c - %m%n" - PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - PatternLayout "%l - %m%n" - PatternLayout "%C.%M.%L - %m%n" - -FileAppender: (BufferedIO=true) - - PatternLayout "%p - %m%n" - PatternLayout "%-5p - %m%n" - PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - PatternLayout "%r [%t] %-5p %c - %m%n" - PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - PatternLayout "%l - %m%n" - PatternLayout "%C.%M.%L - %m%n" - diff --git a/tests/resources/history/torino0.txt b/tests/resources/history/torino0.txt deleted file mode 100644 index 57db2d5d8f..0000000000 --- a/tests/resources/history/torino0.txt +++ /dev/null @@ -1,41 +0,0 @@ -Torino is a AMD Athlon XP 2600+ running Linux 2.6.7 and Sun's JDK 1.4.2. - -NullAppender: - - 4 SimpleLayout - 4 PatternLayout "%p - %m%n" - 4 PatternLayout "%-5p - %m%n" - 10 TTCCLayout/RELATIVE - 10 PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - 10 PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - 10 PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - 9 PatternLayout "%r [%t] %-5p %c - %m%n" - 25 TTCCLayout/ISO8601 - 28 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 58 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - 1309 PatternLayout "%l - %m%n" - 1379 PatternLayout "%C.%M.%L - %m%n" - -FileAppender: - - 26 SimpleLayout - 28 PatternLayout "%p - %m%n" - 47 TTCC/RELATIVE - 46 PatternLayout "%r [%t] %-5p %c %x - %m%n" - 70 TTCCLayout/ISO8601 - 75 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 99 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - 1524 PatternLayout "%l - %m%n" - -FileAppender: (ImmediateFlush=false) - - 20 SimpleLayout - 21 PatternLayout "%p - %m%n" - 38 TTCC/RELATIVE - 38 PatternLayout "%r [%t] %-5p %c %x - %m%n" - 62 TTCCLayout/ISO8601 - 67 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 86 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - -Notice the small but noticable performance gain when forgoing -immediate flush. diff --git a/tests/resources/history/torino1.txt b/tests/resources/history/torino1.txt deleted file mode 100644 index 076adc96f1..0000000000 --- a/tests/resources/history/torino1.txt +++ /dev/null @@ -1,60 +0,0 @@ -Torino is a AMD Athlon XP 2600+ running Linux 2.6.7 and Sun's JDK 1.4.2. - -NullAppender: - - 4.67 PatternLayout "%p - %m%n" - 4.67 PatternLayout "%-5p - %m%n" - 11.22 PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - 11.34 PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - 11.30 PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - 10.04 PatternLayout "%r [%t] %-5p %c - %m%n" - 18.21 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 18.11 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - 183.81 PatternLayout "%l - %m%n" - 203.25 PatternLayout "%C.%M.%L - %m%n" - -FileAppender: - - 15.11 PatternLayout "%p - %m%n" - 16.96 PatternLayout "%-5p - %m%n" - 24.60 PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - 24.37 PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - 25.72 PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - 23.09 PatternLayout "%r [%t] %-5p %c - %m%n" - 35.80 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 36.26 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - 243.57 PatternLayout "%l - %m%n" - 258.75 PatternLayout "%C.%M.%L - %m%n" - -FileAppender: (ImmediateFlush=false) - - 6.96 PatternLayout "%p - %m%n" - 7.07 PatternLayout "%-5p - %m%n" - 15.33 PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - 15.18 PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - 16.49 PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - 14.21 PatternLayout "%r [%t] %-5p %c - %m%n" - 23.33 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 23.13 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - 241.42 PatternLayout "%l - %m%n" - 260.15 PatternLayout "%C.%M.%L - %m%n" - -FileAppender: (BufferedIO=true) - - 6.27 PatternLayout "%p - %m%n" - 6.39 PatternLayout "%-5p - %m%n" - 15.45 PatternLayout "%r [%t] %-5p %c{2} %x - %m%n" - 13.97 PatternLayout "%r [%t] %-5p %.10c %x - %m%n" - 14.40 PatternLayout "%r [%t] %-5p %.20c %x - %m%n" - 13.10 PatternLayout "%r [%t] %-5p %c - %m%n" - 21.78 PatternLayout "%d{ISO8601} [%t] %-5p %c %x - %m%n" - 21.64 PatternLayout "%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c %x - %m%n" - 214.99 PatternLayout "%l - %m%n" - 239.34 PatternLayout "%C.%M.%L - %m%n" - -Notice the small but noticable performance gain when -ImmediateFlush=false - -Note also that BufferedIO yeilds better performance than -ImmediateFlush only when the length of the log entry is relatively -long. diff --git a/tests/resources/jetty.jndi.properties b/tests/resources/jetty.jndi.properties deleted file mode 100644 index d471870fad..0000000000 --- a/tests/resources/jetty.jndi.properties +++ /dev/null @@ -1,2 +0,0 @@ -java.naming.factory.url.pkgs=org.mortbay.jndi -java.naming.factory.initial=org.mortbay.jndi.InitialContextFactory \ No newline at end of file diff --git a/tests/resources/org/apache/log4j/TestLogMFPatterns.properties b/tests/resources/org/apache/log4j/TestLogMFPatterns.properties new file mode 100644 index 0000000000..88df125f7a --- /dev/null +++ b/tests/resources/org/apache/log4j/TestLogMFPatterns.properties @@ -0,0 +1,24 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +Iteration0=Iteration {0} +Hello1=Hello, World +Malformed=Hello, {. +Hello2=Hello, {0}World +Hello3=Hello, {0} +Hello4={1}, {0}. +Hello5={1}{2} {0}. +Hello6={1}{2} {0}{3} diff --git a/tests/resources/org/apache/log4j/TestLogSFPatterns.properties b/tests/resources/org/apache/log4j/TestLogSFPatterns.properties new file mode 100644 index 0000000000..e771863a53 --- /dev/null +++ b/tests/resources/org/apache/log4j/TestLogSFPatterns.properties @@ -0,0 +1,24 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +Iteration0=Iteration {} +Hello1=Hello, World +Malformed=Hello, {. +Hello2=Hello, {}World +Hello3=Hello, {} +Hello4={}, {}. +Hello5={}{} {}. +Hello6={}{} {}{} diff --git a/tests/resources/org/apache/log4j/rewrite/map.log b/tests/resources/org/apache/log4j/rewrite/map.log new file mode 100644 index 0000000000..3ce933f832 --- /dev/null +++ b/tests/resources/org/apache/log4j/rewrite/map.log @@ -0,0 +1,3 @@ +INFO org.apache.log4j.rewrite.RewriteAppenderTest - p1: p2: Message 0 +INFO org.apache.log4j.rewrite.RewriteAppenderTest - p1:Hello p2:World {p1=Hello, p2=World, x1=Mundo} +INFO org.apache.log4j.rewrite.RewriteAppenderTest - p1:Hello p2:World Message 1 diff --git a/tests/resources/org/apache/log4j/rewrite/map.xml b/tests/resources/org/apache/log4j/rewrite/map.xml new file mode 100644 index 0000000000..7cb60b7c85 --- /dev/null +++ b/tests/resources/org/apache/log4j/rewrite/map.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/resources/org/apache/log4j/rewrite/property.log b/tests/resources/org/apache/log4j/rewrite/property.log new file mode 100644 index 0000000000..9aa2c49913 --- /dev/null +++ b/tests/resources/org/apache/log4j/rewrite/property.log @@ -0,0 +1,2 @@ +INFO org.apache.log4j.rewrite.RewriteAppenderTest - p1:Hello p2:World Message 0 +INFO org.apache.log4j.rewrite.RewriteAppenderTest - p1:Hola p2:World Message 1 diff --git a/tests/resources/org/apache/log4j/rewrite/property.xml b/tests/resources/org/apache/log4j/rewrite/property.xml new file mode 100644 index 0000000000..13a04f8e2c --- /dev/null +++ b/tests/resources/org/apache/log4j/rewrite/property.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/resources/org/apache/log4j/rewrite/reflection.log b/tests/resources/org/apache/log4j/rewrite/reflection.log new file mode 100644 index 0000000000..da0b52f2dc --- /dev/null +++ b/tests/resources/org/apache/log4j/rewrite/reflection.log @@ -0,0 +1,3 @@ +INFO org.apache.log4j.rewrite.RewriteAppenderTest - p1: p2: Message 0 +INFO org.apache.log4j.rewrite.RewriteAppenderTest - p1: p2:Hello I am bean. +INFO org.apache.log4j.rewrite.RewriteAppenderTest - p1:Hola p2:Hello Welcome to The Hub diff --git a/tests/resources/org/apache/log4j/rewrite/reflection.xml b/tests/resources/org/apache/log4j/rewrite/reflection.xml new file mode 100644 index 0000000000..643850b2ad --- /dev/null +++ b/tests/resources/org/apache/log4j/rewrite/reflection.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/resources/reffs.jndi.properties b/tests/resources/reffs.jndi.properties deleted file mode 100644 index 2976e06420..0000000000 --- a/tests/resources/reffs.jndi.properties +++ /dev/null @@ -1,3 +0,0 @@ -java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory -java.naming.provider.url=file:.output/jndi - diff --git a/tests/run-tests.bat b/tests/run-tests.bat new file mode 100755 index 0000000000..11d463dab6 --- /dev/null +++ b/tests/run-tests.bat @@ -0,0 +1,111 @@ +rem Licensed to the Apache Software Foundation (ASF) under one or more +rem contributor license agreements. See the NOTICE file distributed with +rem this work for additional information regarding copyright ownership. +rem The ASF licenses this file to You under the Apache License, Version 2.0 +rem (the "License"); you may not use this file except in compliance with +rem the License. You may obtain a copy of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, software +rem distributed under the License is distributed on an "AS IS" BASIS, +rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +rem See the License for the specific language governing permissions and +rem limitations under the License. +rem Batch file for running tests on JDK 1.1 +rem +SET CLASSPATH=\java\junit3.8.1\junit.jar;\java\crimson-1.1.3\crimson.jar;\java\jakarta-oro-2.0.8\jakarta-oro-2.0.8.jar;target\classes;..\..\target\classes;resources;%log4j.jar% +mkdir target +mkdir target\classes +cd src\java +javac -d ..\..\target\classes org\apache\log4j\util\SerializationTestHelper.java +javac -d ..\..\target\classes org\apache\log4j\spi\LoggingEventTest.java +javac -d ..\..\target\classes org\apache\log4j\LevelTest.java +javac -d ..\..\target\classes org\apache\log4j\FileAppenderTest.java +javac -d ..\..\target\classes org\apache\log4j\PriorityTest.java +javac -d ..\..\target\classes org\apache\log4j\CategoryTest.java +javac -d ..\..\target\classes org\apache\log4j\LogManagerTest.java +javac -d ..\..\target\classes org\apache\log4j\helpers\LogLogTest.java +javac -d ..\..\target\classes org\apache\log4j\LayoutTest.java +javac -d ..\..\target\classes org\apache\log4j\helpers\DateLayoutTest.java +javac -d ..\..\target\classes org\apache\log4j\TTCCLayoutTest.java +javac -d ..\..\target\classes org\apache\log4j\xml\XMLLayoutTest.java +javac -d ..\..\target\classes org\apache\log4j\HTMLLayoutTest.java +javac -d ..\..\target\classes org\apache\log4j\PatternLayoutTest.java +javac -d ..\..\target\classes org\apache\log4j\spi\ThrowableInformationTest.java +javac -d ..\..\target\classes org\apache\log4j\spi\LocationInfoTest.java +javac -d ..\..\target\classes org\apache\log4j\PropertyConfiguratorTest.java +javac -d ..\..\target\classes org\apache\log4j\CoreTestSuite.java +javac -d ..\..\target\classes org\apache\log4j\util\UnexpectedFormatException.java +javac -d ..\..\target\classes org\apache\log4j\util\Filter.java +javac -d ..\..\target\classes org\apache\log4j\util\Compare.java +javac -d ..\..\target\classes org\apache\log4j\util\ControlFilter.java +javac -d ..\..\target\classes org\apache\log4j\util\Transformer.java +javac -d ..\..\target\classes org\apache\log4j\util\LineNumberFilter.java +javac -d ..\..\target\classes org\apache\log4j\util\AbsoluteDateAndTimeFilter.java +javac -d ..\..\target\classes org\apache\log4j\MinimumTestCase.java +javac -d ..\..\target\classes org\apache\log4j\VectorAppender.java +javac -d ..\..\target\classes org\apache\log4j\LoggerTestCase.java +javac -d ..\..\target\classes org\apache\log4j\util\ISO8601Filter.java +javac -d ..\..\target\classes org\apache\log4j\util\SunReflectFilter.java +javac -d ..\..\target\classes org\apache\log4j\util\JunitTestRunnerFilter.java +javac -d ..\..\target\classes org\apache\log4j\xml\DOMTestCase.java +javac -d ..\..\target\classes org\apache\log4j\xml\XLevel.java +javac -d ..\..\target\classes org\apache\log4j\xml\CustomLevelTestCase.java +javac -d ..\..\target\classes org\apache\log4j\customLogger\XLogger.java +javac -d ..\..\target\classes org\apache\log4j\customLogger\XLoggerTestCase.java +javac -d ..\..\target\classes org\apache\log4j\defaultInit\TestCase1.java +javac -d ..\..\target\classes org\apache\log4j\defaultInit\TestCase3.java +javac -d ..\..\target\classes org\apache\log4j\defaultInit\TestCase4.java +javac -d ..\..\target\classes org\apache\log4j\util\XMLTimestampFilter.java +javac -d ..\..\target\classes org\apache\log4j\util\XMLLineAttributeFilter.java +javac -d ..\..\target\classes org\apache\log4j\xml\XMLLayoutTestCase.java +javac -d ..\..\target\classes org\apache\log4j\AsyncAppenderTestCase.java +javac -d ..\..\target\classes org\apache\log4j\helpers\OptionConverterTestCase.java +javac -d ..\..\target\classes org\apache\log4j\helpers\BoundedFIFOTestCase.java +javac -d ..\..\target\classes org\apache\log4j\helpers\CyclicBufferTestCase.java +javac -d ..\..\target\classes org\apache\log4j\or\ORTestCase.java +javac -d ..\..\target\classes org\apache\log4j\varia\LevelMatchFilterTestCase.java +javac -d ..\..\target\classes org\apache\log4j\helpers\PatternParserTestCase.java +javac -d ..\..\target\classes org\apache\log4j\util\AbsoluteTimeFilter.java +javac -d ..\..\target\classes org\apache\log4j\util\RelativeTimeFilter.java +javac -d ..\..\target\classes org\apache\log4j\PatternLayoutTestCase.java +javac -d ..\..\target\classes org\apache\log4j\MyPatternParser.java +javac -d ..\..\target\classes org\apache\log4j\MyPatternLayout.java +javac -d ..\..\target\classes org\apache\log4j\VectorErrorHandler.java +javac -d ..\..\target\classes org\apache\log4j\DRFATestCase.java +cd ..\.. +mkdir output +java junit.textui.TestRunner org.apache.log4j.CoreTestSuite +java junit.textui.TestRunner org.apache.log4j.MinimumTestCase +java junit.textui.TestRunner org.apache.log4j.LoggerTestCase +java junit.textui.TestRunner org.apache.log4j.xml.DOMTestCase +java junit.textui.TestRunner org.apache.log4j.xml.CustomLevelTestCase +java junit.textui.TestRunner org.apache.log4j.customLogger.XLoggerTestCase +del target\classes\log4j.xml +del target\classes\log4j.properties +java junit.textui.TestRunner org.apache.log4j.defaultInit.TestCase1 +copy input\xml\defaultInit.xml target\classes\log4j.xml +java junit.textui.TestRunner org.apache.log4j.defaultInit.TestCase2 +del target\classes\log4j.xml +copy input\xml\defaultInit.xml target\classes\log4j.xml +java -Dlog4j.defaultInitOverride=true junit.textui.TestRunner org.apache.log4j.defaultInit.TestCase1 +del target\classes\log4j.xml +copy input\defaultInit3.properties target\classes\log4j.properties +java junit.textui.TestRunner org.apache.log4j.defaultInit.TestCase3 +del target\classes\log4j.properties +copy input\xml\defaultInit.xml target\classes\log4j.xml +copy input\defaultInit3.properties target\classes\log4j.properties +java junit.textui.TestRunner org.apache.log4j.defaultInit.TestCase4 +del target\classes\log4j.xml +del target\classes\log4j.properties +java junit.textui.TestRunner org.apache.log4j.xml.XMLLayoutTestCase +java junit.textui.TestRunner org.apache.log4j.AsyncAppenderTestCase +java junit.textui.TestRunner org.apache.log4j.helpers.OptionConverterTestCase +java junit.textui.TestRunner org.apache.log4j.helpers.BoundedFIFOTestCase +java junit.textui.TestRunner org.apache.log4j.helpers.CyclicBufferTestCase +java junit.textui.TestRunner org.apache.log4j.or.ORTestCase +java junit.textui.TestRunner org.apache.log4j.varia.LevelMatchFilterTestCase +java junit.textui.TestRunner org.apache.log4j.helpers.PatternParserTestCase +java junit.textui.TestRunner org.apache.log4j.PatternLayoutTestCase +java junit.textui.TestRunner org.apache.log4j.DRFATestCase diff --git a/tests/servlet.xml b/tests/servlet.xml deleted file mode 100644 index f136fa8835..0000000000 --- a/tests/servlet.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/src/java/org/apache/log4j/AbstractAppenderTest.java b/tests/src/java/org/apache/log4j/AbstractAppenderTest.java deleted file mode 100644 index d973864368..0000000000 --- a/tests/src/java/org/apache/log4j/AbstractAppenderTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j; - -import java.io.Writer; - -import org.apache.log4j.net.SMTPAppenderTest; -import org.apache.log4j.spi.LoggingEvent; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - - -/** - * An abstract test case which can be subclassed to derived to check the - * certain (limited) aspects of Appender implementations. - * - * @author Ceki Gülcü - * - */ -abstract public class AbstractAppenderTest extends TestCase { - - abstract protected AppenderSkeleton getAppender(); - abstract protected AppenderSkeleton getConfiguredAppender(); - - - public class DummyLayout extends Layout { - public String format(LoggingEvent event) { return ""; } - public void activateOptions() {} - } - - public void testNewAppender() { - // new appenders whould be inactive - AppenderSkeleton appender = getAppender(); - assertFalse( appender.isActive()); - assertFalse(appender.isClosed()); - - appender.close(); - assertTrue(appender.isClosed()); - } - - public void testConfiguredAppender() { - AppenderSkeleton appender = getConfiguredAppender(); - appender.activateOptions(); - assertTrue(appender.isActive()); - assertFalse(appender.isClosed()); - - appender.close(); - assertTrue(appender.isClosed()); - } - - - public static Test suite() { - TestSuite suite = new TestSuite(); - suite.addTestSuite(WriterAppenderTest.class); - suite.addTestSuite(ConsoleAppenderTest.class); - suite.addTestSuite(FileAppenderTest.class); - suite.addTestSuite(SMTPAppenderTest.class); - return suite; - } - -} diff --git a/tests/src/java/org/apache/log4j/AsyncAppenderTestCase.java b/tests/src/java/org/apache/log4j/AsyncAppenderTestCase.java index daab5be792..32544e86e3 100644 --- a/tests/src/java/org/apache/log4j/AsyncAppenderTestCase.java +++ b/tests/src/java/org/apache/log4j/AsyncAppenderTestCase.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,435 +19,134 @@ import junit.framework.TestCase; -import org.apache.log4j.spi.LoggingEvent; - -import java.util.Enumeration; import java.util.Vector; +import org.apache.log4j.spi.LoggingEvent; /** - * Tests for AsyncAppender. - * - * @author Curt Arnold - * + A superficial but general test of log4j. */ -public final class AsyncAppenderTestCase extends TestCase { - /** - * root logger. - */ - private final Logger root = Logger.getRootLogger(); - - /** - * appender under test. - */ - private AsyncAppender asyncAppender; - - /** - * Create new instance of test. - * @param name test name. - */ - public AsyncAppenderTestCase(final String name) { - super(name); - } +public class AsyncAppenderTestCase extends TestCase { - /** - * Create a vector appender with a 10 ms delay. - * @return new VectorAppender. - */ - private static VectorAppender createDelayedAppender() { - VectorAppender vectorAppender = new VectorAppender(); - vectorAppender.setDelay(10); - - return vectorAppender; + public AsyncAppenderTestCase(String name) { + super(name); } - /** - * Create new appender and attach to root logger. - * @param wrappedAppender appender wrapped by async logger. - * @param bufferSize buffer size. - * @return new AsyncAppender. - */ - private static AsyncAppender createAsyncAppender( - final Appender wrappedAppender, final int bufferSize) { - AsyncAppender async = new AsyncAppender(); - async.addAppender(wrappedAppender); - async.setBufferSize(bufferSize); - async.activateOptions(); - Logger.getRootLogger().addAppender(async); - - return async; + public void setUp() { } - /** - * Performs post test cleanup. - */ public void tearDown() { - if (asyncAppender != null) { - asyncAppender.close(); - } - LogManager.shutdown(); } - /** - * Tests writing to an AsyncAppender after calling close. - */ - public void testClose() { - VectorAppender vectorAppender = createDelayedAppender(); - asyncAppender = - createAsyncAppender(vectorAppender, AsyncAppender.DEFAULT_BUFFER_SIZE); - asyncAppender.setName("async-testClose"); + // this test checks whether it is possible to write to a closed AsyncAppender + public void closeTest() throws Exception { + Logger root = Logger.getRootLogger(); + VectorAppender vectorAppender = new VectorAppender(); + AsyncAppender asyncAppender = new AsyncAppender(); + asyncAppender.setName("async-CloseTest"); + asyncAppender.addAppender(vectorAppender); + root.addAppender(asyncAppender); root.debug("m1"); asyncAppender.close(); root.debug("m2"); - + Vector v = vectorAppender.getVector(); - assertEquals(1, v.size()); - assertTrue(vectorAppender.isClosed()); - } - - /** - * Tests that bad appenders do not silently fail forever - * on the dispatching thread. - * - * @throws InterruptedException if test is interrupted while sleeping. - */ - public void testBadAppender() throws InterruptedException { - Appender nullPointerAppender = new NullPointerAppender(); - asyncAppender = - createAsyncAppender( - nullPointerAppender, AsyncAppender.DEFAULT_BUFFER_SIZE); - - // - // NullPointerException should kill dispatching thread - // before sleep returns. - root.info("Message"); - Thread.sleep(100); - - try { - // - // subsequent call should be synchronous - // and result in a NullPointerException on this thread. - root.info("Message"); - fail("Should have thrown exception"); - } catch (NullPointerException ex) { - assertNotNull(ex); - } + assertEquals(v.size(), 1); } - /** - * Test logging to AsyncAppender from many threads. - * @throws InterruptedException if test is interrupted while sleeping. - */ - public void testManyLoggingThreads() throws InterruptedException { - BlockableVectorAppender blockableAppender = new BlockableVectorAppender(); - asyncAppender = createAsyncAppender(blockableAppender, 5); - - // - // create threads - // - final int threadCount = 10; - Thread[] threads = new Thread[threadCount]; - final int repetitions = 20; - Greeter greeter = new Greeter(root, repetitions); - - for (int i = 0; i < threads.length; i++) { - threads[i] = new Thread(greeter); - } - - // - // block underlying appender - synchronized (blockableAppender.getMonitor()) { - // - // start threads holding for queue to open up - for (int i = 0; i < threads.length; i++) { - threads[i].start(); - } - } - - // dispatcher now running free - // - // wait until all threads complete - for (int i = 0; i < threads.length; i++) { - threads[i].join(2000); - assertFalse(threads[i].isAlive()); - } + // this test checks whether appenders embedded within an AsyncAppender are also + // closed + public void test2() { + Logger root = Logger.getRootLogger(); + VectorAppender vectorAppender = new VectorAppender(); + AsyncAppender asyncAppender = new AsyncAppender(); + asyncAppender.setName("async-test2"); + asyncAppender.addAppender(vectorAppender); + root.addAppender(asyncAppender); + root.debug("m1"); asyncAppender.close(); - assertEquals( - threadCount * repetitions, blockableAppender.getVector().size()); + root.debug("m2"); + + Vector v = vectorAppender.getVector(); + assertEquals(v.size(), 1); + assertTrue(vectorAppender.isClosed()); } - /** - * Tests interruption handling on logging threads. - - * @throws InterruptedException if test is interrupted while sleeping. - */ - public void testInterruptWhileLogging() throws InterruptedException { - BlockableVectorAppender blockableAppender = new BlockableVectorAppender(); - asyncAppender = createAsyncAppender(blockableAppender, 5); - - Thread greeter = new Thread(new Greeter(root, 100)); - - synchronized (blockableAppender.getMonitor()) { - // Start greeter - greeter.start(); - - // Give it enough time to fill buffer - Thread.sleep(100); + // this test checks whether appenders embedded within an AsyncAppender are also + // closed + public void test3() { + int LEN = 200; + Logger root = Logger.getRootLogger(); + VectorAppender vectorAppender = new VectorAppender(); + AsyncAppender asyncAppender = new AsyncAppender(); + asyncAppender.setName("async-test3"); + asyncAppender.addAppender(vectorAppender); + root.addAppender(asyncAppender); - // - // Interrupt should stop greeter after next logging event - greeter.interrupt(); + for(int i = 0; i < LEN; i++) { + root.debug("message"+i); } - - greeter.join(); + + System.out.println("Done loop."); + System.out.flush(); asyncAppender.close(); - - Vector events = blockableAppender.getVector(); - - // - // 0-5 popped off of buffer by dispatcher before being blocked - // 5 in buffer before it filled up - // 1 before Thread.sleep in greeter - assertTrue(events.size() <= 11); - } - - /** - * Tests interruption handling in AsyncAppender.close. - * - * @throws InterruptedException if test is interrupted while sleeping. - * - */ - public void testInterruptWhileClosing() throws InterruptedException { - BlockableVectorAppender blockableAppender = new BlockableVectorAppender(); - asyncAppender = createAsyncAppender(blockableAppender, 5); - - Thread greeter = new Thread(new Greeter(root, 100)); - Thread closer = new Thread(new Closer(asyncAppender)); - - synchronized (blockableAppender.getMonitor()) { - greeter.start(); - Thread.sleep(100); - closer.start(); - Thread.sleep(100); - closer.interrupt(); - } - - greeter.join(); - closer.join(); - } - - /** - * Tests killing the dispatch thread. - * - * @throws InterruptedException if test is interrupted while sleeping. - * - */ - public void testInterruptDispatcher() throws InterruptedException { - BlockableVectorAppender blockableAppender = new BlockableVectorAppender(); - asyncAppender = createAsyncAppender(blockableAppender, 5); - assertTrue(asyncAppender.getAllAppenders().hasMoreElements()); - root.info("Hello, World"); - - // - // sleep long enough for that to get dispatched - // - Thread.sleep(50); - - Thread dispatcher = blockableAppender.getDispatcher(); - assertNotNull(dispatcher); - dispatcher.interrupt(); - Thread.sleep(50); - root.info("Hello, World"); - - // - // interrupting the dispatch thread should - // degrade to synchronous dispatching of logging requests - Enumeration iter = asyncAppender.getAllAppenders(); - assertTrue(iter.hasMoreElements()); - assertSame(blockableAppender, iter.nextElement()); - assertFalse(iter.hasMoreElements()); - assertEquals(2, blockableAppender.getVector().size()); - } - - /** - * Tests getBufferSize. - */ - public void testGetBufferSize() { - asyncAppender = new AsyncAppender(); - assertEquals( - AsyncAppender.DEFAULT_BUFFER_SIZE, asyncAppender.getBufferSize()); - } - - /** - * Tests setBufferSize(0). - */ - public void testSetBufferSizeZero() { - VectorAppender vectorAppender = createDelayedAppender(); - asyncAppender = createAsyncAppender(vectorAppender, 0); - assertEquals(1, asyncAppender.getBufferSize()); - - // - // any logging request will deadlock. - root.debug("m1"); root.debug("m2"); - asyncAppender.close(); - + Vector v = vectorAppender.getVector(); - assertEquals(2, v.size()); - } - - /** - * Tests setBufferSize(-10). - */ - public void testSetBufferSizeNegative() { - asyncAppender = new AsyncAppender(); - - try { - asyncAppender.setBufferSize(-10); - fail("Should have thrown NegativeArraySizeException"); - } catch (NegativeArraySizeException ex) { - assertNotNull(ex); - } - } - - /** - * Tests getAllAppenders. - */ - public void testGetAllAppenders() { - VectorAppender vectorAppender = createDelayedAppender(); - asyncAppender = createAsyncAppender(vectorAppender, 5); - - Enumeration iter = asyncAppender.getAllAppenders(); - assertTrue(iter.hasMoreElements()); - assertSame(vectorAppender, iter.nextElement()); - assertFalse(iter.hasMoreElements()); - } - - /** - * Tests getAppender. - */ - public void testGetAppender() { - VectorAppender vectorAppender = createDelayedAppender(); - vectorAppender.setName("test"); - asyncAppender = createAsyncAppender(vectorAppender, 5); - - Appender appender = asyncAppender.getAppender("test"); - assertSame(vectorAppender, appender); + assertEquals(v.size(), LEN); + assertTrue(vectorAppender.isClosed()); } - /** - * Test getLocationInfo. - */ - public void testGetLocationInfo() { - asyncAppender = new AsyncAppender(); - assertFalse(asyncAppender.getLocationInfo()); - } + private static class NullPointerAppender extends AppenderSkeleton { + public NullPointerAppender() { + } - /** - * Tests isAttached. - */ - public void testIsAttached() { - VectorAppender vectorAppender = createDelayedAppender(); - asyncAppender = createAsyncAppender(vectorAppender, 5); - assertTrue(asyncAppender.isAttached(vectorAppender)); - assertFalse(asyncAppender.isAttached(asyncAppender)); - assertFalse(asyncAppender.isAttached(new BlockableVectorAppender())); - } - /** - * Tests requiresLayout. - * - * @deprecated feature under test is deprecated. - */ - public void testRequiresLayout() { - asyncAppender = new AsyncAppender(); - assertFalse(asyncAppender.requiresLayout()); - } + /** + This method is called by the {@link org.apache.log4j.AppenderSkeleton#doAppend} + method. - /** - * Tests removeAllAppenders. - */ - public void testRemoveAllAppenders() { - VectorAppender vectorAppender = createDelayedAppender(); - asyncAppender = new AsyncAppender(); - asyncAppender.addAppender(vectorAppender); - assertTrue(asyncAppender.getAllAppenders().hasMoreElements()); - asyncAppender.removeAllAppenders(); + */ + public void append(org.apache.log4j.spi.LoggingEvent event) { + throw new NullPointerException(); + } - Enumeration iter = asyncAppender.getAllAppenders(); - assertTrue((iter == null) || !iter.hasMoreElements()); - } + public void close() { + } - /** - * Tests removeAppender(Appender). - */ - public void testRemoveAppender() { - VectorAppender vectorAppender = createDelayedAppender(); - vectorAppender.setName("test"); - asyncAppender = new AsyncAppender(); - asyncAppender.addAppender(vectorAppender); - assertTrue(asyncAppender.getAllAppenders().hasMoreElements()); - - VectorAppender appender2 = new VectorAppender(); - appender2.setName("test"); - asyncAppender.removeAppender(appender2); - assertTrue(asyncAppender.getAllAppenders().hasMoreElements()); - asyncAppender.removeAppender(vectorAppender); - assertFalse(asyncAppender.getAllAppenders().hasMoreElements()); - } + public boolean requiresLayout() { + return false; + } + } - /** - * Tests removeAppender(String). - */ - public void testRemoveAppenderByName() { - VectorAppender vectorAppender = createDelayedAppender(); - vectorAppender.setName("test"); - asyncAppender = new AsyncAppender(); - asyncAppender.addAppender(vectorAppender); - assertTrue(asyncAppender.getAllAppenders().hasMoreElements()); - asyncAppender.removeAppender("TEST"); - assertTrue(asyncAppender.getAllAppenders().hasMoreElements()); - asyncAppender.removeAppender("test"); - assertFalse(asyncAppender.getAllAppenders().hasMoreElements()); - } /** - * Tests discarding of messages when buffer is full. + * Tests that a bad appender will switch async back to sync. + * See bug 23021 + * @since 1.2.12 + * @throws Exception thrown if Thread.sleep is interrupted */ - public void testDiscard() { - BlockableVectorAppender blockableAppender = new BlockableVectorAppender(); - asyncAppender = createAsyncAppender(blockableAppender, 5); - assertTrue(asyncAppender.getBlocking()); - asyncAppender.setBlocking(false); - assertFalse(asyncAppender.getBlocking()); - Greeter greeter = new Greeter(root, 100); - synchronized(blockableAppender.getMonitor()) { - greeter.run(); - root.error("That's all folks."); - } - asyncAppender.close(); - Vector events = blockableAppender.getVector(); - // - // 0-5 event pulled from buffer by dispatcher before blocking - // 5 events in buffer - // 1 summary event - // - assertTrue(events.size() <= 11); - // - // last message should start with "Discarded" - LoggingEvent event = (LoggingEvent) events.get(events.size() - 1); - assertEquals("Discarded", event.getMessage().toString().substring(0, 9)); - assertSame(Level.ERROR, event.getLevel()); - for (int i = 0; i < events.size() - 1; i++) { - event = (LoggingEvent) events.get(i); - assertEquals("Hello, World", event.getMessage().toString()); + public void testBadAppender() throws Exception { + Appender nullPointerAppender = new NullPointerAppender(); + AsyncAppender asyncAppender = new AsyncAppender(); + asyncAppender.addAppender(nullPointerAppender); + asyncAppender.setBufferSize(5); + asyncAppender.activateOptions(); + Logger root = Logger.getRootLogger(); + root.addAppender(nullPointerAppender); + try { + root.info("Message"); + Thread.sleep(10); + root.info("Message"); + fail("Should have thrown exception"); + } catch(NullPointerException ex) { + } } - /** * Tests location processing when buffer is full and locationInfo=true. * See bug 41186. @@ -515,193 +214,126 @@ public void testLocationInfoFalse() { } /** - * Tests behavior when wrapped appender - * makes log request on dispatch thread. - * - * See bug 30106 - */ - public void testLoggingInDispatcher() throws InterruptedException { - BlockableVectorAppender appender = new BlockableVectorAppender(); - asyncAppender = - createAsyncAppender(appender, 2); - // - // triggers several log requests on dispatch thread - // - root.fatal("Anybody up there..."); - Thread.sleep(100); - asyncAppender.close(); - - Vector events = appender.getVector(); - // - // last message should start with "Discarded" - LoggingEvent event = (LoggingEvent) events.get(events.size() - 1); - assertEquals("Discarded", event.getMessage().toString().substring(0, 9)); - } - - - /** - * Appender that throws a NullPointerException on calls to append. - * Used to test behavior of AsyncAppender when dispatching to - * misbehaving appenders. - */ - private static final class NullPointerAppender extends AppenderSkeleton { - /** - * Create new instance. - */ - public NullPointerAppender() { - super(true); - } - - /** - * {@inheritDoc} + * Logging request runnable. */ - public void append(final LoggingEvent event) { - throw new NullPointerException(); - } + private static final class Greeter implements Runnable { + /** + * Logger. + */ + private final Logger logger; + + /** + * Repetitions. + */ + private final int repetitions; + + /** + * Create new instance. + * @param logger logger, may not be null. + * @param repetitions repetitions. + */ + public Greeter(final Logger logger, final int repetitions) { + if (logger == null) { + throw new IllegalArgumentException("logger"); + } - /** - * {@inheritDoc} - */ - public void close() { - } + this.logger = logger; + this.repetitions = repetitions; + } - /** - * {@inheritDoc} - */ - public boolean requiresLayout() { - return false; + /** + * {@inheritDoc} + */ + public void run() { + try { + for (int i = 0; i < repetitions; i++) { + logger.info("Hello, World"); + Thread.sleep(1); + } + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } } - } - /** - * Logging request runnable. - */ - private static final class Greeter implements Runnable { - /** - * Logger. - */ - private final Logger logger; - /** - * Repetitions. - */ - private final int repetitions; /** - * Create new instance. - * @param logger logger, may not be null. - * @param repetitions repetitions. + * Vector appender that can be explicitly blocked. */ - public Greeter(final Logger logger, final int repetitions) { - if (logger == null) { - throw new IllegalArgumentException("logger"); + private static final class BlockableVectorAppender extends VectorAppender { + /** + * Monitor object used to block appender. + */ + private final Object monitor = new Object(); + + + /** + * Create new instance. + */ + public BlockableVectorAppender() { + super(); } - this.logger = logger; - this.repetitions = repetitions; - } - - /** - * {@inheritDoc} - */ - public void run() { - try { - for (int i = 0; i < repetitions; i++) { - logger.info("Hello, World"); - Thread.sleep(1); + /** + * {@inheritDoc} + */ + public void append(final LoggingEvent event) { + synchronized (monitor) { + super.append(event); + // + // if fatal, echo messages for testLoggingInDispatcher + // + if (event.getLevel() == Level.FATAL) { + Logger logger = Logger.getLogger(event.getLoggerName()); + logger.error(event.getMessage().toString()); + logger.warn(event.getMessage().toString()); + logger.info(event.getMessage().toString()); + logger.debug(event.getMessage().toString()); + } } - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); } - } - } - - /** - * Vector appender that can be explicitly blocked. - */ - private static final class BlockableVectorAppender extends VectorAppender { - /** - * Monitor object used to block appender. - */ - private final Object monitor = new Object(); - - /** - * Thread of last call to append. - */ - private Thread dispatcher; - - /** - * Create new instance. - */ - public BlockableVectorAppender() { - super(); - } - /** - * {@inheritDoc} - */ - public void append(final LoggingEvent event) { - synchronized (monitor) { - dispatcher = Thread.currentThread(); - super.append(event); - // - // if fatal, echo messages for testLoggingInDispatcher - // - if (event.getLevel() == Level.FATAL) { - Logger logger = event.getLogger(); - logger.error(event.getMessage().toString()); - logger.warn(event.getMessage().toString()); - logger.info(event.getMessage().toString()); - logger.debug(event.getMessage().toString()); - } + /** + * Get monitor object. + * @return monitor. + */ + public Object getMonitor() { + return monitor; } - } - /** - * Get monitor object. - * @return monitor. - */ - public Object getMonitor() { - return monitor; } - /** - * Get thread of previous call to append. - * @return thread, may be null. - */ - public Thread getDispatcher() { - synchronized (monitor) { - return dispatcher; - } - } - } - /** - * Closes appender. - */ - private static final class Closer implements Runnable { /** - * Appender. + * Test that a mutable message object is evaluated before + * being placed in the async queue. + * See bug 43559. */ - private final AsyncAppender appender; + public void testMutableMessage() { + BlockableVectorAppender blockableAppender = new BlockableVectorAppender(); + AsyncAppender async = new AsyncAppender(); + async.addAppender(blockableAppender); + async.setBufferSize(5); + async.setLocationInfo(false); + async.activateOptions(); + Logger rootLogger = Logger.getRootLogger(); + rootLogger.addAppender(async); + StringBuffer buf = new StringBuffer("Hello"); + synchronized(blockableAppender.getMonitor()) { + rootLogger.info(buf); + buf.append(", World."); + } + async.close(); + Vector events = blockableAppender.getVector(); + LoggingEvent event = (LoggingEvent) events.get(0); + PatternLayout layout = new PatternLayout(); + layout.setConversionPattern("%m"); + layout.activateOptions(); + String msg = layout.format(event); + assertEquals("Hello", msg); + } - /** - * Create new instance. - * @param appender appender, may not be null. - */ - public Closer(final AsyncAppender appender) { - if (appender == null) { - throw new IllegalArgumentException("appender"); - } - this.appender = appender; - } - /** - * {@inheritDoc} - */ - public void run() { - appender.close(); - } - } } diff --git a/tests/src/java/org/apache/log4j/CategoryTest.java b/tests/src/java/org/apache/log4j/CategoryTest.java index 563326c442..cd65e2703c 100644 --- a/tests/src/java/org/apache/log4j/CategoryTest.java +++ b/tests/src/java/org/apache/log4j/CategoryTest.java @@ -19,12 +19,7 @@ import junit.framework.TestCase; -import java.io.StringWriter; import java.lang.reflect.Method; -import java.util.Locale; -import java.util.ResourceBundle; - -import org.apache.log4j.spi.LoggingEvent; /** @@ -41,25 +36,6 @@ public class CategoryTest extends TestCase { public CategoryTest(final String name) { super(name); } - - StringWriter sw = new StringWriter(); - Priority debug = Level.DEBUG; - Logger logger = Logger.getLogger("org.example.foo"); - - protected void setUp() { - WriterAppender a = new WriterAppender(); - a.setWriter(sw); - a.setLayout(new PatternLayout("%m ")); - a.activateOptions(); - BasicConfigurator.configure(a); - Category.getRoot().setLevel(Level.ALL); - Category.getRoot().setResourceBundle(getTestBundle()); - logger.setLevel(Level.ALL); - } - - static ResourceBundle getTestBundle() { - return ResourceBundle.getBundle("L7D", new Locale("en", "US")); - } /** * Tests Category.forcedLog. @@ -84,64 +60,20 @@ public void testGetChainedPriorityReturnType() throws Exception { * Tests l7dlog(Priority, String, Throwable). */ public void testL7dlog() { - logger.l7dlog(debug, "test", (Throwable)null); - assertEquals("This is the English, US test.", sw.toString().trim()); - } - - /** - * Tests l7dlog(Priority, String) log. - */ - public void testL7dlog2() { - logger.l7dlog(debug, "test"); - assertEquals("This is the English, US test.", sw.toString().trim()); - } - - /** - * Tests l7dlog(Priority, String, Throwable) no resource. - */ - public void testL7dlogNoResource() { - logger.l7dlog(debug, "XYZ", (Throwable)null); - assertEquals("No resource is associated with key \"XYZ\". XYZ ", sw.toString()); - } - - /** - * Tests l7dlog(Priority, String, Throwable) log nothing. - */ - public void testL7dlogNothing() { + Logger logger = Logger.getLogger("org.example.foo"); logger.setLevel(Level.ERROR); - logger.l7dlog(debug, "msg1", (Throwable)null); - assertEquals("no logging", "", sw.toString()); - } - - /** - * Tests l7dlog(FQN, Priority, String, Object[], Throwable) log. - */ - public void testL7dlogFormat() { - Object o[] = new Object[] { new Integer(1), "X" }; - logger.l7dlog(debug, "msg1", o, null); - assertEquals("This is test number 1 with string argument X. ", sw.toString()); - } - - /** - * Tests l7dlog(FQN, Priority, String, Object[]) log. - */ - public void testL7dlogFormat2() { - Object o[] = new Object[] { new Integer(1), "X" }; - logger.l7dlog(debug, "msg1", o); - assertEquals("This is test number 1 with string argument X. ", sw.toString()); + Priority debug = Level.DEBUG; + logger.l7dlog(debug, "Hello, World", null); } /** - * Tests l7dlog(FQN, Priority, String, Object[], Throwable) log. - * @since 1.3 + * Tests l7dlog(Priority, String, Object[], Throwable). */ - public void testL7dlogFQN() { - VectorAppender va = new VectorAppender(); - logger.addAppender(va); - logger.l7dlog("myFQN", debug, "msg1", new Object[0], new Throwable()); - LoggingEvent le = (LoggingEvent) va.getVector().get(0); - assertEquals("myFQN", le.getFQNOfLoggerClass()); - assertNotNull(le.getThrowableInformation()); + public void testL7dlog4Param() { + Logger logger = Logger.getLogger("org.example.foo"); + logger.setLevel(Level.ERROR); + Priority debug = Level.DEBUG; + logger.l7dlog(debug, "Hello, World", new Object[0], null); } /** diff --git a/tests/src/java/org/apache/log4j/ConsoleAppenderTest.java b/tests/src/java/org/apache/log4j/ConsoleAppenderTest.java deleted file mode 100644 index a52d2a46f1..0000000000 --- a/tests/src/java/org/apache/log4j/ConsoleAppenderTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.log4j; - - -/** - * Test if ConsoleAppender honors the Appender contract. - * - * @author Ceki Gülcü - * - */ -public class ConsoleAppenderTest extends AbstractAppenderTest { - protected AppenderSkeleton getAppender() { - return new ConsoleAppender(); - } - - protected AppenderSkeleton getConfiguredAppender() { - ConsoleAppender ca = new ConsoleAppender(); - - // set a bogus layout - ca.setLayout(new DummyLayout()); - return ca; - } - - public void testPartiallyConfiguredAppender() { - ConsoleAppender wa1 = new ConsoleAppender(); - assertFalse(wa1.isActive()); - } -} diff --git a/tests/src/java/org/apache/log4j/CoreTestSuite.java b/tests/src/java/org/apache/log4j/CoreTestSuite.java index 9427c59000..82ab97de4c 100644 --- a/tests/src/java/org/apache/log4j/CoreTestSuite.java +++ b/tests/src/java/org/apache/log4j/CoreTestSuite.java @@ -18,29 +18,25 @@ import junit.framework.Test; import junit.framework.TestSuite; +import org.apache.log4j.spi.LoggingEventTest; /** * Suite of log4j class level unit tests. * - * @author Curt Arnold - * @since 1.3 */ public class CoreTestSuite { /** * Constructs test suite. * @return test suite - * @deprecated since some tests in suite test deprecated classes. */ public static Test suite() { TestSuite s = new TestSuite(); - s.addTestSuite(org.apache.log4j.pattern.NameAbbreviatorTest.class); - s.addTestSuite(org.apache.log4j.pattern.PatternParserTest.class); - s.addTestSuite(org.apache.log4j.rolling.helper.FileNamePatternTestCase.class); - s.addTestSuite(org.apache.log4j.pattern.FormattingInfoTest.class); + s.addTestSuite(LoggingEventTest.class); s.addTestSuite(org.apache.log4j.LevelTest.class); s.addTestSuite(org.apache.log4j.PriorityTest.class); s.addTestSuite(org.apache.log4j.CategoryTest.class); + s.addTestSuite(org.apache.log4j.FileAppenderTest.class); s.addTestSuite(org.apache.log4j.LogManagerTest.class); s.addTestSuite(org.apache.log4j.helpers.LogLogTest.class); s.addTestSuite(org.apache.log4j.LayoutTest.class); @@ -50,7 +46,21 @@ public static Test suite() { s.addTestSuite(org.apache.log4j.HTMLLayoutTest.class); s.addTestSuite(org.apache.log4j.PatternLayoutTest.class); s.addTestSuite(org.apache.log4j.spi.LoggingEventTest.class); + s.addTestSuite(org.apache.log4j.spi.ThrowableInformationTest.class); + s.addTestSuite(org.apache.log4j.spi.LocationInfoTest.class); s.addTestSuite(org.apache.log4j.PropertyConfiguratorTest.class); + s.addTestSuite(org.apache.log4j.net.SMTPAppenderTest.class); + s.addTestSuite(org.apache.log4j.net.TelnetAppenderTest.class); + s.addTestSuite(org.apache.log4j.DefaultThrowableRendererTest.class); + s.addTestSuite(org.apache.log4j.EnhancedThrowableRendererTest.class); + s.addTestSuite(org.apache.log4j.TestLogXF.class); + s.addTestSuite(org.apache.log4j.TestLogMF.class); + s.addTestSuite(org.apache.log4j.TestLogSF.class); + s.addTestSuite(org.apache.log4j.pattern.CachedDateFormatTest.class); + s.addTestSuite(org.apache.log4j.pattern.FormattingInfoTest.class); + s.addTestSuite(org.apache.log4j.pattern.NameAbbreviatorTest.class); + s.addTestSuite(org.apache.log4j.pattern.PatternParserTest.class); + s.addTestSuite(org.apache.log4j.helpers.UtilLoggingLevelTest.class); return s; } } diff --git a/tests/src/java/org/apache/log4j/DRFATestCase.java b/tests/src/java/org/apache/log4j/DRFATestCase.java index 1c77136a82..8d0417422f 100644 --- a/tests/src/java/org/apache/log4j/DRFATestCase.java +++ b/tests/src/java/org/apache/log4j/DRFATestCase.java @@ -20,11 +20,13 @@ import junit.framework.TestCase; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.FileInputStream; +import java.text.SimpleDateFormat; import java.util.Calendar; -import java.util.TimeZone; import java.util.Date; -import java.text.SimpleDateFormat; +import org.apache.log4j.util.Compare; /** Exhaustive test of the DailyRollingFileAppender compute algorithm. @@ -51,7 +53,6 @@ public void tearDown() { /** * Test prediction of check period. - * @deprecated since class under test is deprecated. */ public void testComputeCheckPeriod() { @@ -60,8 +61,7 @@ void testComputeCheckPeriod() { drfa.setDatePattern("yyyy-MM-dd.'log'"); drfa.activateOptions(); - int x = drfa.computeCheckPeriod(); - int y = DailyRollingFileAppender.TOP_OF_DAY; + drfa.computeCheckPeriod(); assertEquals(drfa.computeCheckPeriod(), DailyRollingFileAppender.TOP_OF_DAY); @@ -89,7 +89,6 @@ void testComputeCheckPeriod() { /** * Test of RollingCalendar. - * @deprecated since class under test is deprecated. */ public void testRC1() { @@ -132,7 +131,6 @@ void testRC1() { /** * RollingCalendar test. - * @deprecated since class under test is deprecated. */ public void testRC2() { @@ -141,7 +139,6 @@ void testRC2() { rc.setType(DailyRollingFileAppender.TOP_OF_HOUR); Calendar c = Calendar.getInstance(); - TimeZone tz = c.getTimeZone(); // jan, mar, may, july, aug, oct, dec have 31 days int [] M31 = {0,2,4,6,7,9,11}; @@ -204,7 +201,6 @@ void testRC2() { /** * RollingCalendar test. - * @deprecated since class under test is deprecated. */ public void testRC3() { @@ -285,7 +281,6 @@ void testRC3() { * Common test code for 3 parameter constructor. * * @throws IOException if IOException during test. - * @deprecated since class under test is deprecated. */ public void test3Param(final String datePattern, final String filename) throws IOException { @@ -303,7 +298,6 @@ public void test3Param(final String datePattern, * Creates an appender with an unrecognized top-of-year pattern. * * @throws IOException if IOException during test. - * @deprecated since class under test is deprecated. */ public void testTopOfYear() throws IOException { try { @@ -318,7 +312,6 @@ public void testTopOfYear() throws IOException { * Creates an appender with a top-of-month pattern. * * @throws IOException if IOException during test. - * @deprecated since class under test is deprecated. */ public void testTopOfMonth() throws IOException { test3Param("'.'yyyy-MM", "output/drfa_topOfMonth.log"); @@ -329,7 +322,6 @@ public void testTopOfMonth() throws IOException { * Creates an appender with a top-of-week pattern. * * @throws IOException if IOException during test. - * @deprecated since class under test is deprecated. */ public void testTopOfWeek() throws IOException { test3Param("'.'yyyy-w", "output/drfa_topOfWeek.log"); @@ -339,7 +331,6 @@ public void testTopOfWeek() throws IOException { * Creates an appender with a top-of-day pattern. * * @throws IOException if IOException during test. - * @deprecated since class under test is deprecated. */ public void testTopOfDay() throws IOException { test3Param("'.'yyyy-MM-dd", "output/drfa_topOfDay.log"); @@ -350,7 +341,6 @@ public void testTopOfDay() throws IOException { * Creates an appender with a half day pattern. * * @throws IOException if IOException during test. - * @deprecated since class under test is deprecated. */ public void testHalfDay() throws IOException { test3Param("'.'yyyy-MM-dd-a", "output/drfa_halfDay.log"); @@ -360,7 +350,6 @@ public void testHalfDay() throws IOException { * Creates an appender with a top-of-hour pattern. * * @throws IOException if IOException during test. - * @deprecated since class under test is deprecated. */ public void testTopOfHour() throws IOException { test3Param("'.'yyyy-MM-dd-HH", "output/drfa_topOfHour.log"); @@ -370,7 +359,6 @@ public void testTopOfHour() throws IOException { * Creates an appender with a top-of-day pattern. * * @throws IOException if IOException during test. - * @deprecated since class under test is deprecated. */ public void testTopOfMinute() throws IOException { test3Param("'.'yyyy-MM-dd-HH-mm", "output/drfa_topOfMinute.log"); @@ -380,7 +368,6 @@ public void testTopOfMinute() throws IOException { * Attempts to rollOver with no date pattern set. * * @throws IOException if IOException during test. - * @deprecated since class under test is deprecated. */ public void testRolloverNoPattern() throws IOException { Layout layout = new SimpleLayout(); @@ -400,7 +387,6 @@ public void testRolloverNoPattern() throws IOException { * * @throws IOException * @throws InterruptedException - * @deprecated since class under test is deprecated. */ public void testMinuteRollover() throws IOException, InterruptedException { Layout layout = new SimpleLayout(); @@ -436,4 +422,91 @@ public void testMinuteRollover() throws IOException, InterruptedException { } + /** + * Naive append method to combine rollover fragments. + * @param combined stream to which source is appended. + * @param source stream containing bytes to append. + * @param buf byte array to use in transfer. + * @throws IOException if io error during operation. + */ + private static void append(final FileOutputStream combined, + final FileInputStream source, + final byte[] buf) throws IOException { + int count1 = source.read(buf); + if (count1 > 0) { + combined.write(buf, 0, count1); + } + source.close(); + } + + /** + * Tests rollOver when log file is unabled to be renamed. + * See bug 43374. + * + * @throws IOException if io error. + * @throws InterruptedException if test interrupted while waiting for the start of the next minute. + */ + public void testBlockedRollover() throws IOException, InterruptedException { + Layout layout = new SimpleLayout(); + String filename = "output/drfa_blockedRollover.log"; + String pattern = "'.'yyyy-MM-dd-HH-mm"; + + + Date start = new Date(); + DailyRollingFileAppender appender = + new DailyRollingFileAppender(layout, + filename, + pattern); + appender.setAppend(false); + Logger root = Logger.getRootLogger(); + root.addAppender(appender); + // + // open next two anticipated rollover file names + // + File block1 = new File(filename + new SimpleDateFormat(pattern).format(start)); + File block2 = new File(filename + new SimpleDateFormat(pattern).format( + new Date(start.getTime() + 60000))); + FileOutputStream os1 = new FileOutputStream(block1); + FileOutputStream os2 = new FileOutputStream(block2); + root.info("Prior to rollover"); + // + // sleep until three seconds into next minute + // + Thread.sleep(63000 - (start.getTime() % 60000)); + // + // should trigger failed rollover + // + root.info("Rollover attempt while blocked"); + os1.close(); + os2.close(); + root.info("Message after block removed"); + appender.close(); + // + // combine base file and potential rollovers + // since rollover may or may not have been blocked + // depending on platform. + // + String combinedFilename = "output/drfa_blockedRollover.combined"; + FileOutputStream combined = new FileOutputStream(combinedFilename); + byte[] buf = new byte[500]; + append(combined, new FileInputStream(block1), buf); + append(combined, new FileInputStream(block2), buf); + append(combined, new FileInputStream(filename), buf); + combined.close(); + assertTrue(Compare.compare(combinedFilename, + "witness/drfa_blockedRollover.log")); + } + + /** Check that the computed rollover period for a pattern containing a week as the finest unit is set to be + * a week. Due to a locale mismatch this was incorrect in non-English locales. See bug 40888. + * + */ + public void testWeeklyRollover() { + DailyRollingFileAppender drfa = new DailyRollingFileAppender(); + drfa.setDatePattern("'.'yyyy-ww"); + int checkPeriod = drfa.computeCheckPeriod(); + assertEquals(DailyRollingFileAppender.TOP_OF_WEEK, checkPeriod); + } + + } diff --git a/tests/src/java/org/apache/log4j/DeadlockTest.java b/tests/src/java/org/apache/log4j/DeadlockTest.java deleted file mode 100644 index 1d9122af8f..0000000000 --- a/tests/src/java/org/apache/log4j/DeadlockTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j; - -import junit.framework.TestCase; - - -/** - * Test case for bug http://nagoya.apache.org/bugzilla/show_bug.cgi?id=24159 - * - * Actually this one is impossible to fix. - * - * @author Elias Ross - * @author Ceki Gulcu - */ -public class DeadlockTest extends TestCase { - static long RUNLENGTH = 10000; - Logger logger = Logger.getLogger("DeadlockTest"); - - public DeadlockTest() { - super("DeadlockTest"); - } - - protected void setUp() throws Exception { - super.setUp(); - System.out.println("in setup"); - BasicConfigurator.configure(); - } - - protected void tearDown() throws Exception { - super.tearDown(); - System.out.println("tear down"); - LogManager.shutdown(); - } - - public void testDeadlock() throws InterruptedException { - System.out.println("in testDeadlock()"); - - final Deadlock d = new Deadlock(); - - Thread t1 = - new Thread() { - public void run() { - long start = System.currentTimeMillis(); - - while ((System.currentTimeMillis() - start) < RUNLENGTH) { - logger.debug(d); - } - } - }; - - Thread t2 = - new Thread() { - public void run() { - long start = System.currentTimeMillis(); - - while ((System.currentTimeMillis() - start) < RUNLENGTH) { - d.setVar("n"); - } - } - }; - - t1.start(); - t2.start(); - System.out.println("Waiting to join t1."); - t1.join(); - System.out.println("======================Joined t1====================="); - } -} - - -class Deadlock { - static final Logger log = Logger.getLogger(Deadlock.class); - String var; - - public synchronized void setVar(String var) { - log.debug(this); - } - - public synchronized String getVar() { - return var; - } - - public String toString() { - return "Value x=" + getVar(); - } -} diff --git a/tests/src/java/org/apache/log4j/DefaultThrowableRendererTest.java b/tests/src/java/org/apache/log4j/DefaultThrowableRendererTest.java new file mode 100644 index 0000000000..5b574770dc --- /dev/null +++ b/tests/src/java/org/apache/log4j/DefaultThrowableRendererTest.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j; + +import junit.framework.TestCase; +import org.apache.log4j.spi.ThrowableRenderer; + +public class DefaultThrowableRendererTest extends TestCase { + public DefaultThrowableRendererTest(final String name) { + super(name); + } + + public void testDefaultRender() { + ThrowableRenderer r = new DefaultThrowableRenderer(); + Exception ex = new Exception(); + String[] strRep = r.doRender(ex); + assertNotNull(strRep); + assertTrue(strRep.length > 0); + for(int i = 0; i < strRep.length; i++) { + assertNotNull(strRep[i]); + } + } +} diff --git a/tests/src/java/org/apache/log4j/EncodingTest.java b/tests/src/java/org/apache/log4j/EncodingTest.java deleted file mode 100644 index ac287386c9..0000000000 --- a/tests/src/java/org/apache/log4j/EncodingTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j; - -import junit.framework.TestCase; - -import org.apache.log4j.util.BinaryCompare; - - -/** - * Tests support for encoding specification. - * @author Curt Arnold - * @since 1.3 - */ -public class EncodingTest extends TestCase { - /** - * Construct an instance of EncodingTest. - * @param name test name - */ - public EncodingTest(final String name) { - super(name); - } - - /** - * Resets configuration after each test. - */ - public void tearDown() { - Logger.getRootLogger().getLoggerRepository().resetConfiguration(); - } - - /** - * Test us-ascii encoding. - * @throws Exception if test failure - */ - public void testASCII() throws Exception { - Logger root = Logger.getRootLogger(); - configure(root, "output/ascii.log", "US-ASCII"); - common(root); - assertTrue(BinaryCompare.compare("output/ascii.log", - "witness/encoding/ascii.log")); - } - - /** - * Test iso-8859-1 encoding. - * @throws Exception if test failure - */ - public void testLatin1() throws Exception { - Logger root = Logger.getRootLogger(); - configure(root, "output/latin1.log", "iso-8859-1"); - common(root); - assertTrue(BinaryCompare.compare("output/latin1.log", - "witness/encoding/latin1.log")); - } - - /** - * Test utf-8 encoding. - * @throws Exception if test failure. - */ - public void testUtf8() throws Exception { - Logger root = Logger.getRootLogger(); - configure(root, "output/UTF-8.log", "UTF-8"); - common(root); - assertTrue(BinaryCompare.compare("output/UTF-8.log", - "witness/encoding/UTF-8.log")); - } - - /** - * Test utf-16 encoding. - * @throws Exception if test failure. - */ - public void testUtf16() throws Exception { - Logger root = Logger.getRootLogger(); - configure(root, "output/UTF-16.log", "UTF-16"); - common(root); - assertTrue(BinaryCompare.compare("output/UTF-16.log", - "witness/encoding/UTF-16.log")); - } - - /** - * Test utf-16be encoding. - * @throws Exception if test failure. - */ - public void testUtf16BE() throws Exception { - Logger root = Logger.getRootLogger(); - configure(root, "output/UTF-16BE.log", "UTF-16BE"); - common(root); - assertTrue(BinaryCompare.compare("output/UTF-16BE.log", - "witness/encoding/UTF-16BE.log")); - } - - /** - * Test utf16-le encoding. - * @throws Exception if test failure. - */ - public void testUtf16LE() throws Exception { - Logger root = Logger.getRootLogger(); - configure(root, "output/UTF-16LE.log", "UTF-16LE"); - common(root); - assertTrue(BinaryCompare.compare("output/UTF-16LE.log", - "witness/encoding/UTF-16LE.log")); - } - - /** - * Configure logging. - * @param logger logger - * @param filename logging file name - * @param encoding encoding - */ - private void configure(final Logger logger, final String filename, - final String encoding) { - PatternLayout layout = new PatternLayout(); - layout.setConversionPattern("%p - %m\\n"); - layout.activateOptions(); - - FileAppender appender = new FileAppender(); - appender.setFile(filename); - appender.setEncoding(encoding); - appender.setAppend(false); - appender.setLayout(layout); - appender.activateOptions(); - logger.addAppender(appender); - logger.setLevel(Level.INFO); - } - - /** - * Common logging requests. - * @param logger logger - */ - private void common(final Logger logger) { - logger.info("Hello, World"); - - // pi can be encoded in iso-8859-1 - logger.info("\u00b9"); - - // one each from Latin, Arabic, Armenian, Bengali, CJK and Cyrillic - logger.info("A\u0605\u0530\u0986\u4E03\u0400"); - } -} diff --git a/tests/src/java/org/apache/log4j/EnhancedMyPatternLayout.java b/tests/src/java/org/apache/log4j/EnhancedMyPatternLayout.java new file mode 100644 index 0000000000..4ec375ceb5 --- /dev/null +++ b/tests/src/java/org/apache/log4j/EnhancedMyPatternLayout.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j; +import org.apache.log4j.helpers.PatternParser; + +/** + + Example showing how to extend EnhancedPatternLayout to recognize additional + conversion characters. + +

    In this case MyPatternLayout recognizes %# conversion pattern. It + outputs the value of an internal counter which is also incremented + at each call. + +

    See source code + for more details. + + @see MyPatternParser + @see org.apache.log4j.EnhancedPatternLayout + @author Anders Kristensen +*/ +public class EnhancedMyPatternLayout extends EnhancedPatternLayout { + public + EnhancedMyPatternLayout() { + this(DEFAULT_CONVERSION_PATTERN); + } + + public + EnhancedMyPatternLayout(String pattern) { + super(pattern); + } + + public + PatternParser createPatternParser(String pattern) { + return new MyPatternParser( + pattern == null ? DEFAULT_CONVERSION_PATTERN : pattern); + } +} diff --git a/tests/src/java/org/apache/log4j/EnhancedPatternLayoutTest.java b/tests/src/java/org/apache/log4j/EnhancedPatternLayoutTest.java new file mode 100644 index 0000000000..39d5767652 --- /dev/null +++ b/tests/src/java/org/apache/log4j/EnhancedPatternLayoutTest.java @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j; + +import org.apache.log4j.spi.LoggingEvent; + + +/** + * Test for EnhancedPatternLayout. + * + */ +public class EnhancedPatternLayoutTest extends LayoutTest { + /** + * Construct new instance of PatternLayoutTest. + * + * @param testName test name. + */ + public EnhancedPatternLayoutTest(final String testName) { + super(testName, "text/plain", true, null, null); + } + + /** + * @{inheritDoc} + */ + protected Layout createLayout() { + return new EnhancedPatternLayout("[%t] %p %c - %m%n"); + } + + /** + * Tests format. + */ + public void testFormat() { + Logger logger = Logger.getLogger("org.apache.log4j.LayoutTest"); + LoggingEvent event = + new LoggingEvent( + "org.apache.log4j.Logger", logger, Level.INFO, "Hello, World", null); + EnhancedPatternLayout layout = (EnhancedPatternLayout) createLayout(); + String result = layout.format(event); + StringBuffer buf = new StringBuffer(100); + buf.append('['); + buf.append(event.getThreadName()); + buf.append("] "); + buf.append(event.getLevel().toString()); + buf.append(' '); + buf.append(event.getLoggerName()); + buf.append(" - "); + buf.append(event.getMessage()); + buf.append(System.getProperty("line.separator")); + assertEquals(buf.toString(), result); + } + + /** + * Tests getPatternFormat(). + */ + public void testGetPatternFormat() { + EnhancedPatternLayout layout = (EnhancedPatternLayout) createLayout(); + assertEquals("[%t] %p %c - %m%n", layout.getConversionPattern()); + } + + /** + * Tests DEFAULT_CONVERSION_PATTERN constant. + */ + public void testDefaultConversionPattern() { + assertEquals("%m%n", EnhancedPatternLayout.DEFAULT_CONVERSION_PATTERN); + } + + /** + * Tests DEFAULT_CONVERSION_PATTERN constant. + */ + public void testTTCCConversionPattern() { + assertEquals( + "%r [%t] %p %c %x - %m%n", EnhancedPatternLayout.TTCC_CONVERSION_PATTERN); + } + + /** + * Tests buffer downsizing code path. + */ + public void testFormatResize() { + Logger logger = Logger.getLogger("org.apache.log4j.xml.PatternLayoutTest"); + NDC.clear(); + + char[] msg = new char[2000]; + + for (int i = 0; i < msg.length; i++) { + msg[i] = 'A'; + } + + LoggingEvent event1 = + new LoggingEvent( + "org.apache.log4j.Logger", logger, Level.DEBUG, new String(msg), null); + EnhancedPatternLayout layout = (EnhancedPatternLayout) createLayout(); + String result = layout.format(event1); + LoggingEvent event2 = + new LoggingEvent( + "org.apache.log4j.Logger", logger, Level.WARN, "Hello, World", null); + result = layout.format(event2); + assertEquals("[", result.substring(0, 1)); + } + + /** + * Class to ensure that protected members are still available. + */ + public static final class DerivedPatternLayout extends EnhancedPatternLayout { + /** + * Constructs a new instance of DerivedPatternLayout. + */ + public DerivedPatternLayout() { + } + + /** + * Get BUF_SIZE. + * @return return initial buffer size in characters. + * @deprecated + */ + public int getBufSize() { + return BUF_SIZE; + } + + /** + * Get MAX_CAPACITY. + * @return maximum capacity in characters. + * @deprecated + */ + public int getMaxCapacity() { + return MAX_CAPACITY; + } + } +} diff --git a/tests/src/java/org/apache/log4j/EnhancedPatternLayoutTestCase.java b/tests/src/java/org/apache/log4j/EnhancedPatternLayoutTestCase.java new file mode 100644 index 0000000000..e97c42f737 --- /dev/null +++ b/tests/src/java/org/apache/log4j/EnhancedPatternLayoutTestCase.java @@ -0,0 +1,589 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j; + +import junit.framework.TestCase; +import org.apache.log4j.util.AbsoluteDateAndTimeFilter; +import org.apache.log4j.util.AbsoluteTimeFilter; +import org.apache.log4j.util.Compare; +import org.apache.log4j.util.ControlFilter; +import org.apache.log4j.util.Filter; +import org.apache.log4j.util.ISO8601Filter; +import org.apache.log4j.util.EnhancedJunitTestRunnerFilter; +import org.apache.log4j.util.EnhancedLineNumberFilter; +import org.apache.log4j.util.RelativeTimeFilter; +import org.apache.log4j.util.SunReflectFilter; +import org.apache.log4j.util.Transformer; +import org.apache.log4j.MDCOrderFilter; +import org.apache.log4j.spi.ThrowableInformation; + +import java.text.ParsePosition; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; +import java.io.*; + + +public class EnhancedPatternLayoutTestCase extends TestCase { + static String TEMP = "output/temp"; + static String FILTERED = "output/filtered"; + static String EXCEPTION1 = "java.lang.Exception: Just testing"; + static String EXCEPTION2 = "\\s*at .*\\(.*\\)"; + static String EXCEPTION3 = "\\s*at .*\\((Native Method|Unknown Source)\\)"; + static String EXCEPTION4 = "\\s*at .*\\(.*Compiled Code\\)"; + + static String PAT0 = + "\\[main]\\ (DEBUG|INFO|WARN|ERROR|FATAL) .* - Message \\d{1,2}"; + static String PAT1 = Filter.ISO8601_PAT + " " + PAT0; + static String PAT2 = Filter.ABSOLUTE_DATE_AND_TIME_PAT + " " + PAT0; + static String PAT3 = Filter.ABSOLUTE_TIME_PAT + " " + PAT0; + static String PAT4 = Filter.RELATIVE_TIME_PAT + " " + PAT0; + static String PAT5 = + "\\[main]\\ (DEBUG|INFO|WARN|ERROR|FATAL) .* : Message \\d{1,2}"; + static String PAT6 = + "\\[main]\\ (DEBUG|INFO |WARN |ERROR|FATAL) org.apache.log4j.EnhancedPatternLayoutTestCase.common\\(EnhancedPatternLayoutTestCase.java(:\\d{1,4})?\\): Message \\d{1,2}"; + static String PAT11a = + "^(DEBUG|INFO |WARN |ERROR|FATAL) \\[main]\\ log4j.EnhancedPatternLayoutTest: Message \\d{1,2}"; + static String PAT11b = + "^(DEBUG|INFO |WARN |ERROR|FATAL) \\[main]\\ root: Message \\d{1,2}"; + static String PAT12 = + "^\\[main]\\ (DEBUG|INFO |WARN |ERROR|FATAL) " + + "org.apache.log4j.EnhancedPatternLayoutTestCase.common\\(EnhancedPatternLayoutTestCase.java:\\d{3}\\): " + + "Message \\d{1,2}"; + static String PAT13 = + "^\\[main]\\ (DEBUG|INFO |WARN |ERROR|FATAL) " + + "apache.log4j.EnhancedPatternLayoutTestCase.common\\(EnhancedPatternLayoutTestCase.java:\\d{3}\\): " + + "Message \\d{1,2}"; + static String PAT14 = + "^(TRACE|DEBUG| INFO| WARN|ERROR|FATAL)\\ \\d{1,2}\\ *- Message \\d{1,2}"; + static String PAT_MDC_1 = ""; + Logger root; + Logger logger; + + + public EnhancedPatternLayoutTestCase(final String name) { + super(name); + } + + public void setUp() { + root = Logger.getRootLogger(); + logger = Logger.getLogger(EnhancedPatternLayoutTest.class); + } + + public void tearDown() { + root.getLoggerRepository().resetConfiguration(); + } + + /** + * Configures log4j from a properties file resource in class loader path. + * @param fileName resource name, only last element is significant. + * @throws IOException if resource not found or error reading resource. + */ + private static void configure(final String fileName) throws IOException { + PropertyConfigurator.configure(fileName); + } + + /** + * Compares actual and expected files. + * @param actual file name for file generated by test + * @param expected resource name containing expected output + * @return true if files are the same after adjustments + * @throws IOException if IO error during comparison. + */ + private static boolean compare(final String actual, + final String expected) throws IOException { + return Compare.compare(actual, expected); + } + + public void test1() throws Exception { + configure("input/pattern/enhancedPatternLayout1.properties"); + common(); + Transformer.transform( + TEMP, FILTERED, + new Filter[] { + new EnhancedLineNumberFilter(), new SunReflectFilter(), + new EnhancedJunitTestRunnerFilter() + }); + assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.1")); + } + + public void test2() throws Exception { + configure("input/pattern/enhancedPatternLayout2.properties"); + common(); + + ControlFilter cf1 = + new ControlFilter( + new String[] { PAT1, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + Transformer.transform( + TEMP, FILTERED, + new Filter[] { + cf1, new EnhancedLineNumberFilter(), new ISO8601Filter(), + new SunReflectFilter(), new EnhancedJunitTestRunnerFilter() + }); + assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.2")); + } + + public void test3() throws Exception { + configure("input/pattern/enhancedPatternLayout3.properties"); + common(); + + ControlFilter cf1 = + new ControlFilter( + new String[] { PAT1, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + Transformer.transform( + TEMP, FILTERED, + new Filter[] { + cf1, new EnhancedLineNumberFilter(), new ISO8601Filter(), + new SunReflectFilter(), new EnhancedJunitTestRunnerFilter() + }); + assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.3")); + } + + // Output format: + // 06 avr. 2002 18:30:58,937 [main] DEBUG atternLayoutTest - Message 0 + public void test4() throws Exception { + configure("input/pattern/enhancedPatternLayout4.properties"); + common(); + + ControlFilter cf1 = + new ControlFilter( + new String[] { PAT2, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + Transformer.transform( + TEMP, FILTERED, + new Filter[] { + cf1, new EnhancedLineNumberFilter(), new AbsoluteDateAndTimeFilter(), + new SunReflectFilter(), new EnhancedJunitTestRunnerFilter() + }); + assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.4")); + } + + public void test5() throws Exception { + configure("input/pattern/enhancedPatternLayout5.properties"); + common(); + + ControlFilter cf1 = + new ControlFilter( + new String[] { PAT2, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + Transformer.transform( + TEMP, FILTERED, + new Filter[] { + cf1, new EnhancedLineNumberFilter(), new AbsoluteDateAndTimeFilter(), + new SunReflectFilter(), new EnhancedJunitTestRunnerFilter() + }); + assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.5")); + } + + // 18:54:19,201 [main] DEBUG atternLayoutTest - Message 0 + public void test6() throws Exception { + configure("input/pattern/enhancedPatternLayout6.properties"); + common(); + + ControlFilter cf1 = + new ControlFilter( + new String[] { PAT3, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + Transformer.transform( + TEMP, FILTERED, + new Filter[] { + cf1, new EnhancedLineNumberFilter(), new AbsoluteTimeFilter(), + new SunReflectFilter(), new EnhancedJunitTestRunnerFilter() + }); + assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.6")); + } + + public void test7() throws Exception { + configure("input/pattern/enhancedPatternLayout7.properties"); + common(); + + ControlFilter cf1 = + new ControlFilter( + new String[] { PAT3, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + Transformer.transform( + TEMP, FILTERED, + new Filter[] { + cf1, new EnhancedLineNumberFilter(), new AbsoluteTimeFilter(), + new SunReflectFilter(), new EnhancedJunitTestRunnerFilter() + }); + assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.7")); + } + + public void test8() throws Exception { + configure("input/pattern/enhancedPatternLayout8.properties"); + common(); + + ControlFilter cf1 = + new ControlFilter( + new String[] { PAT4, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + Transformer.transform( + TEMP, FILTERED, + new Filter[] { + cf1, new EnhancedLineNumberFilter(), new RelativeTimeFilter(), + new SunReflectFilter(), new EnhancedJunitTestRunnerFilter() + }); + assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.8")); + } + + public void test9() throws Exception { + configure("input/pattern/enhancedPatternLayout9.properties"); + common(); + + ControlFilter cf1 = + new ControlFilter( + new String[] { PAT5, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + Transformer.transform( + TEMP, FILTERED, + new Filter[] { + cf1, new EnhancedLineNumberFilter(), new SunReflectFilter(), + new EnhancedJunitTestRunnerFilter() + }); + assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.9")); + } + + public void test10() throws Exception { + configure("input/pattern/enhancedPatternLayout10.properties"); + common(); + + ControlFilter cf1 = + new ControlFilter( + new String[] { PAT6, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + Transformer.transform( + TEMP, FILTERED, + new Filter[] { + cf1, new EnhancedLineNumberFilter(), new SunReflectFilter(), + new EnhancedJunitTestRunnerFilter() + }); + assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.10")); + } + + public void test11() throws Exception { + configure("input/pattern/enhancedPatternLayout11.properties"); + common(); + + ControlFilter cf1 = + new ControlFilter( + new String[] { PAT11a, PAT11b, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + Transformer.transform( + TEMP, FILTERED, + new Filter[] { + cf1, new EnhancedLineNumberFilter(), new SunReflectFilter(), + new EnhancedJunitTestRunnerFilter() + }); + assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.11")); + } + + public void test12() throws Exception { + configure("input/pattern/enhancedPatternLayout12.properties"); + common(); + + ControlFilter cf1 = + new ControlFilter( + new String[] { PAT12, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + Transformer.transform( + TEMP, FILTERED, + new Filter[] { + cf1, new EnhancedLineNumberFilter(), new SunReflectFilter(), + new EnhancedJunitTestRunnerFilter() + }); + assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.12")); + } + + public void test13() throws Exception { + configure("input/pattern/enhancedPatternLayout13.properties"); + common(); + + ControlFilter cf1 = + new ControlFilter( + new String[] { PAT13, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + Transformer.transform( + TEMP, FILTERED, + new Filter[] { + cf1, new EnhancedLineNumberFilter(), new SunReflectFilter(), + new EnhancedJunitTestRunnerFilter() + }); + assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.13")); + } + + /** + * Test of class abbreviation. + * + * @throws Exception + */ + public void test14() throws Exception { + configure("input/pattern/enhancedPatternLayout14.properties"); + common(); + + Transformer.transform( + TEMP, FILTERED, + new Filter[] { + new EnhancedLineNumberFilter(), new SunReflectFilter(), + new EnhancedJunitTestRunnerFilter() + }); + assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.14")); + } + + + private static void clearMDC() throws Exception { + java.util.Hashtable context = MDC.getContext(); + if (context != null) { + context.clear(); + } + } + + public void testMDC1() throws Exception { + configure("input/pattern/enhancedPatternLayout.mdc.1.properties"); + clearMDC(); + MDC.put("key1", "va11"); + MDC.put("key2", "va12"); + logger.debug("Hello World"); + MDC.remove("key1"); + MDC.remove("key2"); + + Transformer.transform( + TEMP, FILTERED, + new Filter[] { + new EnhancedLineNumberFilter(), new SunReflectFilter(), + new EnhancedJunitTestRunnerFilter(), + new MDCOrderFilter() + }); + assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.mdc.1")); + } + /** + * Tests log4j 1.2 style extension of EnhancedPatternLayout. + * Was test14 in log4j 1.2. + * @throws Exception + */ + public void test15() throws Exception { + configure("input/pattern/enhancedPatternLayout15.properties"); + common(); + ControlFilter cf1 = new ControlFilter(new String[]{PAT14, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4}); + Transformer.transform( + TEMP, FILTERED, + new Filter[] { + cf1, new EnhancedLineNumberFilter(), new SunReflectFilter(), + new EnhancedJunitTestRunnerFilter() + }); + assertTrue(compare(FILTERED, "witness/pattern/enhancedPatternLayout.15")); + } + /** + * Tests explicit UTC time zone in pattern. + * @throws Exception + */ + public void test16() throws Exception { + final long start = new Date().getTime(); + configure("input/pattern/enhancedPatternLayout16.properties"); + common(); + final long end = new Date().getTime(); + FileReader reader = new FileReader("output/patternLayout16.log"); + char chars[] = new char[50]; + reader.read(chars, 0, chars.length); + reader.close(); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + format.setTimeZone(TimeZone.getTimeZone("GMT+0")); + String utcStr = new String(chars, 0, 19); + Date utcDate = format.parse(utcStr, new ParsePosition(0)); + assertTrue(utcDate.getTime() >= start - 1000 && utcDate.getTime() < end + 1000); + String cstStr = new String(chars, 21, 19); + format.setTimeZone(TimeZone.getTimeZone("GMT-6")); + Date cstDate = format.parse(cstStr, new ParsePosition(0)); + assertFalse(cstStr.equals(utcStr)); + assertTrue(cstDate.getTime() >= start - 1000 && cstDate.getTime() < end + 1000); + } + + void common() { + int i = -1; + + logger.debug("Message " + ++i); + root.debug("Message " + i); + + logger.info("Message " + ++i); + root.info("Message " + i); + + logger.warn("Message " + ++i); + root.warn("Message " + i); + + logger.error("Message " + ++i); + root.error("Message " + i); + + logger.log(Level.FATAL, "Message " + ++i); + root.log(Level.FATAL, "Message " + i); + + Exception e = new Exception("Just testing"); + + logger.debug("Message " + ++i, e); + logger.info("Message " + ++i, e); + logger.warn("Message " + ++i, e); + logger.error("Message " + ++i, e); + logger.log(Level.FATAL, "Message " + ++i, e); + } + + /** + Test case for MDC conversion pattern. */ + public void testMDC2() throws Exception { + String OUTPUT_FILE = "output/patternLayout.mdc.2"; + String WITNESS_FILE = "witness/pattern/enhancedPatternLayout.mdc.2"; + + String mdcMsgPattern1 = "%m : %X%n"; + String mdcMsgPattern2 = "%m : %X{key1}%n"; + String mdcMsgPattern3 = "%m : %X{key2}%n"; + String mdcMsgPattern4 = "%m : %X{key3}%n"; + String mdcMsgPattern5 = "%m : %X{key1},%X{key2},%X{key3}%n"; + + // set up appender + EnhancedPatternLayout layout = new EnhancedPatternLayout("%m%n"); + Appender appender = new FileAppender(layout, OUTPUT_FILE, false); + + // set appender on root and set level to debug + root.addAppender(appender); + root.setLevel(Level.DEBUG); + + clearMDC(); + // output starting message + root.debug("starting mdc pattern test"); + + layout.setConversionPattern(mdcMsgPattern1); + layout.activateOptions(); + root.debug("empty mdc, no key specified in pattern"); + + layout.setConversionPattern(mdcMsgPattern2); + layout.activateOptions(); + root.debug("empty mdc, key1 in pattern"); + + layout.setConversionPattern(mdcMsgPattern3); + layout.activateOptions(); + root.debug("empty mdc, key2 in pattern"); + + layout.setConversionPattern(mdcMsgPattern4); + layout.activateOptions(); + root.debug("empty mdc, key3 in pattern"); + + layout.setConversionPattern(mdcMsgPattern5); + layout.activateOptions(); + root.debug("empty mdc, key1, key2, and key3 in pattern"); + + MDC.put("key1", "value1"); + MDC.put("key2", "value2"); + + layout.setConversionPattern(mdcMsgPattern1); + layout.activateOptions(); + root.debug("filled mdc, no key specified in pattern"); + + layout.setConversionPattern(mdcMsgPattern2); + layout.activateOptions(); + root.debug("filled mdc, key1 in pattern"); + + layout.setConversionPattern(mdcMsgPattern3); + layout.activateOptions(); + root.debug("filled mdc, key2 in pattern"); + + layout.setConversionPattern(mdcMsgPattern4); + layout.activateOptions(); + root.debug("filled mdc, key3 in pattern"); + + layout.setConversionPattern(mdcMsgPattern5); + layout.activateOptions(); + root.debug("filled mdc, key1, key2, and key3 in pattern"); + + MDC.remove("key1"); + MDC.remove("key2"); + + layout.setConversionPattern("%m%n"); + layout.activateOptions(); + root.debug("finished mdc pattern test"); + + + Transformer.transform( + OUTPUT_FILE, FILTERED, + new Filter[] { + new EnhancedLineNumberFilter(), new SunReflectFilter(), + new EnhancedJunitTestRunnerFilter(), + new MDCOrderFilter() + }); + + assertTrue(compare(FILTERED, WITNESS_FILE)); + } + /** + Test case for throwable conversion pattern. */ + public void testThrowable() throws Exception { + String OUTPUT_FILE = "output/patternLayout.throwable"; + String WITNESS_FILE = "witness/pattern/enhancedPatternLayout.throwable"; + + + // set up appender + EnhancedPatternLayout layout = new EnhancedPatternLayout("%m%n"); + Appender appender = new FileAppender(layout, OUTPUT_FILE, false); + + // set appender on root and set level to debug + root.addAppender(appender); + root.setLevel(Level.DEBUG); + + // output starting message + root.debug("starting throwable pattern test"); + Exception ex = new Exception("Test Exception"); + root.debug("plain pattern, no exception"); + root.debug("plain pattern, with exception", ex); + layout.setConversionPattern("%m%n%throwable"); + layout.activateOptions(); + root.debug("%throwable, no exception"); + root.debug("%throwable, with exception", ex); + + layout.setConversionPattern("%m%n%throwable{short}"); + layout.activateOptions(); + root.debug("%throwable{short}, no exception"); + root.debug("%throwable{short}, with exception", ex); + + layout.setConversionPattern("%m%n%throwable{none}"); + layout.activateOptions(); + root.debug("%throwable{none}, no exception"); + root.debug("%throwable{none}, with exception", ex); + + layout.setConversionPattern("%m%n%throwable{0}"); + layout.activateOptions(); + root.debug("%throwable{0}, no exception"); + root.debug("%throwable{0}, with exception", ex); + + layout.setConversionPattern("%m%n%throwable{1}"); + layout.activateOptions(); + root.debug("%throwable{1}, no exception"); + root.debug("%throwable{1}, with exception", ex); + + layout.setConversionPattern("%m%n%throwable{100}"); + layout.activateOptions(); + root.debug("%throwable{100}, no exception"); + root.debug("%throwable{100}, with exception", ex); + + // + // manufacture a pattern to get just the first two lines + // + String[] trace = new ThrowableInformation(ex).getThrowableStrRep(); + layout.setConversionPattern("%m%n%throwable{" + (2 - trace.length) + "}"); + layout.activateOptions(); + root.debug("%throwable{-n}, no exception"); + root.debug("%throwable{-n}, with exception", ex); + + + Transformer.transform( + OUTPUT_FILE, FILTERED, + new Filter[] { + new EnhancedLineNumberFilter(), new SunReflectFilter(), + new EnhancedJunitTestRunnerFilter(), + new MDCOrderFilter() + }); + + assertTrue(compare(FILTERED, WITNESS_FILE)); + } +} diff --git a/tests/src/java/org/apache/log4j/EnhancedThrowableRendererTest.java b/tests/src/java/org/apache/log4j/EnhancedThrowableRendererTest.java new file mode 100644 index 0000000000..0f7ed21f79 --- /dev/null +++ b/tests/src/java/org/apache/log4j/EnhancedThrowableRendererTest.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j; + +import junit.framework.TestCase; +import org.apache.log4j.spi.ThrowableRenderer; + +/** + * Test for EnhancedThrowableRenderer. + * + */ +public class EnhancedThrowableRendererTest extends TestCase { + /** + * Construct new instance. + * @param name test name. + */ + public EnhancedThrowableRendererTest(final String name) { + super(name); + } + + /** + * Render simple exception. + */ + public void testEnhancedRender() { + ThrowableRenderer r = new EnhancedThrowableRenderer(); + Exception ex = new Exception(); + String[] strRep = r.doRender(ex); + assertNotNull(strRep); + assertTrue(strRep.length > 0); + for(int i = 0; i < strRep.length; i++) { + assertNotNull(strRep[i]); + } + } +} diff --git a/tests/src/java/org/apache/log4j/FileAppenderTest.java b/tests/src/java/org/apache/log4j/FileAppenderTest.java index 901518306b..40fc89529c 100644 --- a/tests/src/java/org/apache/log4j/FileAppenderTest.java +++ b/tests/src/java/org/apache/log4j/FileAppenderTest.java @@ -17,6 +17,8 @@ package org.apache.log4j; +import junit.framework.TestCase; + import java.io.File; import java.lang.reflect.Method; @@ -24,52 +26,33 @@ /** * - * Test if WriterAppender honors the Appender contract. + * FileAppender tests. * - * @author Ceki Gülcü * @author Curt Arnold */ -public class FileAppenderTest extends AbstractAppenderTest { - protected AppenderSkeleton getAppender() { - return new FileAppender(); - } - - protected AppenderSkeleton getConfiguredAppender() { - FileAppender wa = new FileAppender(); - wa.setFile("output/temp"); - wa.setLayout(new DummyLayout()); - - return wa; - } - - public void testPartiallyConfiguredAppender() { - FileAppender wa1 = new FileAppender(); - wa1.setFile("output/temp"); - assertFalse(wa1.isActive()); - - FileAppender wa2 = new FileAppender(); - wa2.setLayout(new DummyLayout()); - assertFalse(wa2.isActive()); - } - +public class FileAppenderTest extends TestCase { /** * Tests that any necessary directories are attempted to * be created if they don't exist. See bug 9150. * */ public void testDirectoryCreation() { - File newFile = new File("output/newdir/temp.log"); - newFile.delete(); - - File newDir = new File("output/newdir"); - newDir.delete(); - - FileAppender wa = new FileAppender(); - wa.setFile("output/newdir/temp.log"); - wa.setLayout(new DummyLayout()); - wa.activateOptions(); - - assertTrue(new File("output/newdir/temp.log").exists()); + // + // known to fail on JDK 1.1 + if (!System.getProperty("java.version").startsWith("1.1.")) { + File newFile = new File("output/newdir/temp.log"); + newFile.delete(); + + File newDir = new File("output/newdir"); + newDir.delete(); + + org.apache.log4j.FileAppender wa = new org.apache.log4j.FileAppender(); + wa.setFile("output/newdir/temp.log"); + wa.setLayout(new PatternLayout("%m%n")); + wa.activateOptions(); + + assertTrue(new File("output/newdir/temp.log").exists()); + } } /** @@ -87,7 +70,6 @@ public void testGetThresholdReturnType() throws Exception { public void testgetSetThreshold() { FileAppender appender = new FileAppender(); Priority debug = Level.DEBUG; - Priority all = Level.ALL; assertNull(appender.getThreshold()); appender.setThreshold(debug); assertTrue(appender.getThreshold() == debug); @@ -95,20 +77,10 @@ public void testgetSetThreshold() { /** * Tests isAsSevereAsThreshold. - * @deprecated */ public void testIsAsSevereAsThreshold() { FileAppender appender = new FileAppender(); Priority debug = Level.DEBUG; assertTrue(appender.isAsSevereAsThreshold(debug)); } - - /** - * Test for bug 38993. - * @throws java.io.IOException if IOException - */ - public void testSetFileBuffered() throws java.io.IOException { - FileAppender appender = new FileAppender(); - appender.setFile("output/setFileBuffered.log", false, true, 100); - } } diff --git a/tests/src/java/org/apache/log4j/HTMLLayoutTest.java b/tests/src/java/org/apache/log4j/HTMLLayoutTest.java index 3d437328c3..7837a2cc09 100644 --- a/tests/src/java/org/apache/log4j/HTMLLayoutTest.java +++ b/tests/src/java/org/apache/log4j/HTMLLayoutTest.java @@ -18,16 +18,14 @@ package org.apache.log4j; import org.apache.log4j.spi.LoggingEvent; - import org.w3c.dom.Document; - import org.xml.sax.InputSource; -import java.io.Reader; -import java.io.StringReader; - import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import java.io.Reader; +import java.io.StringReader; +import java.util.Hashtable; /** @@ -88,7 +86,7 @@ public void testFormat() throws Exception { String src = "]>" + result + ""; - Document doc = parse(src); + parse(src); } /** @@ -174,7 +172,71 @@ public void testFormatResize() { "org.apache.log4j.Logger", logger, Level.WARN, "Hello, World", ex); result = layout.format(event2); assertEquals( - Layout.LINE_SEP + "", + result.substring(0, Layout.LINE_SEP.length() + 4)); } + + + /** + * Level with arbitrary toString value. + */ + private static final class ProblemLevel extends Level { + private static final long serialVersionUID = 1L; + + /** + * Construct new instance. + * @param levelName level name, may not be null. + */ + public ProblemLevel(final String levelName) { + super(6000, levelName, 6); + } + } + + /** + * Tests problematic characters in multiple fields. + * @throws Exception if parser can not be constructed + * or source is not a valid XML document. + */ + public void testProblemCharacters() throws Exception { + String problemName = "com.example.bar<>&\"'"; + Logger logger = Logger.getLogger(problemName); + Level level = new ProblemLevel(problemName); + Exception ex = new IllegalArgumentException(problemName); + String threadName = Thread.currentThread().getName(); + Thread.currentThread().setName(problemName); + NDC.push(problemName); + Hashtable mdcMap = MDC.getContext(); + if (mdcMap != null) { + mdcMap.clear(); + } + MDC.put(problemName, problemName); + LoggingEvent event = + new LoggingEvent( + problemName, logger, level, problemName, ex); + HTMLLayout layout = (HTMLLayout) createLayout(); + String result = layout.format(event); + mdcMap = MDC.getContext(); + if (mdcMap != null) { + mdcMap.clear(); + } + + Thread.currentThread().setName(threadName); + + // + // do a little fixup to make output XHTML + // + StringBuffer buf = new StringBuffer( + "]>"); + buf.append(result); + buf.append("
    "); + String doc = buf.toString(); + for(int i = doc.lastIndexOf("
    "); + i != -1; + i = doc.lastIndexOf("
    ", i - 1)) { + buf.replace(i, i + 4, "
    "); + } + + parse(buf.toString()); + } + } diff --git a/tests/src/java/org/apache/log4j/HierarchyThresholdTestCase.java b/tests/src/java/org/apache/log4j/HierarchyThresholdTestCase.java index a5fbe239e9..3e885bde4f 100644 --- a/tests/src/java/org/apache/log4j/HierarchyThresholdTestCase.java +++ b/tests/src/java/org/apache/log4j/HierarchyThresholdTestCase.java @@ -17,20 +17,20 @@ package org.apache.log4j; -import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import junit.framework.Test; -import org.apache.log4j.util.*; +import org.apache.log4j.util.Compare; import org.apache.log4j.xml.XLevel; - /** Test the configuration of the hierarchy-wide threshold. @author Ceki Gülcü */ public class HierarchyThresholdTestCase extends TestCase { + static String TEMP = "output/temp"; static Logger logger = Logger.getLogger(HierarchyThresholdTestCase.class); @@ -40,70 +40,77 @@ public HierarchyThresholdTestCase(String name) { public void setUp() { } - + public void tearDown() { System.out.println("Tearing down test case."); logger.getLoggerRepository().resetConfiguration(); } - + public void test1() throws Exception { - PropertyConfigurator.configure("input/hierarchy/hierarchyThreshold1.properties"); + PropertyConfigurator.configure("input/hierarchyThreshold1.properties"); common(); - assertTrue(Compare.compare(TEMP, "witness/hierarchy/hierarchyThreshold.1")); + assertTrue(Compare.compare(TEMP, "witness/hierarchyThreshold.1")); } public void test2() throws Exception { - PropertyConfigurator.configure("input/hierarchy/hierarchyThreshold2.properties"); + PropertyConfigurator.configure("input/hierarchyThreshold2.properties"); common(); - assertTrue(Compare.compare(TEMP, "witness/hierarchy/hierarchyThreshold.2")); + assertTrue(Compare.compare(TEMP, "witness/hierarchyThreshold.2")); } public void test3() throws Exception { - PropertyConfigurator.configure("input/hierarchy/hierarchyThreshold3.properties"); + PropertyConfigurator.configure("input/hierarchyThreshold3.properties"); common(); - assertTrue(Compare.compare(TEMP, "witness/hierarchy/hierarchyThreshold.3")); + assertTrue(Compare.compare(TEMP, "witness/hierarchyThreshold.3")); } public void test4() throws Exception { - PropertyConfigurator.configure("input/hierarchy/hierarchyThreshold4.properties"); + PropertyConfigurator.configure("input/hierarchyThreshold4.properties"); common(); - assertTrue(Compare.compare(TEMP, "witness/hierarchy/hierarchyThreshold.4")); + assertTrue(Compare.compare(TEMP, "witness/hierarchyThreshold.4")); } public void test5() throws Exception { - PropertyConfigurator.configure("input/hierarchy/hierarchyThreshold5.properties"); + PropertyConfigurator.configure("input/hierarchyThreshold5.properties"); common(); - assertTrue(Compare.compare(TEMP, "witness/hierarchy/hierarchyThreshold.5")); + assertTrue(Compare.compare(TEMP, "witness/hierarchyThreshold.5")); } public void test6() throws Exception { - PropertyConfigurator.configure("input/hierarchy/hierarchyThreshold6.properties"); + PropertyConfigurator.configure("input/hierarchyThreshold6.properties"); common(); - assertTrue(Compare.compare(TEMP, "witness/hierarchy/hierarchyThreshold.6")); + assertTrue(Compare.compare(TEMP, "witness/hierarchyThreshold.6")); } public void test7() throws Exception { - PropertyConfigurator.configure("input/hierarchy/hierarchyThreshold7.properties"); + PropertyConfigurator.configure("input/hierarchyThreshold7.properties"); common(); - assertTrue(Compare.compare(TEMP, "witness/hierarchy/hierarchyThreshold.7")); + assertTrue(Compare.compare(TEMP, "witness/hierarchyThreshold.7")); } public void test8() throws Exception { - PropertyConfigurator.configure("input/hierarchy/hierarchyThreshold8.properties"); + PropertyConfigurator.configure("input/hierarchyThreshold8.properties"); common(); - assertTrue(Compare.compare(TEMP, "witness/hierarchy/hierarchyThreshold.8")); + assertTrue(Compare.compare(TEMP, "witness/hierarchyThreshold.8")); } - static void common() { + + static + void common() { + String oldThreadName = Thread.currentThread().getName(); + Thread.currentThread().setName("main"); + logger.log(XLevel.TRACE, "m0"); logger.debug("m1"); logger.info("m2"); logger.warn("m3"); logger.error("m4"); logger.fatal("m5"); + + Thread.currentThread().setName(oldThreadName); } - public static Test XXXsuite() { + public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(new HierarchyThresholdTestCase("test1")); suite.addTest(new HierarchyThresholdTestCase("test2")); @@ -113,7 +120,6 @@ public static Test XXXsuite() { suite.addTest(new HierarchyThresholdTestCase("test6")); suite.addTest(new HierarchyThresholdTestCase("test7")); suite.addTest(new HierarchyThresholdTestCase("test8")); - return suite; } } diff --git a/tests/src/java/org/apache/log4j/Last.java b/tests/src/java/org/apache/log4j/Last.java index 635824d4b0..4286ab8ebe 100644 --- a/tests/src/java/org/apache/log4j/Last.java +++ b/tests/src/java/org/apache/log4j/Last.java @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.apache.log4j; diff --git a/tests/src/java/org/apache/log4j/LevelTest.java b/tests/src/java/org/apache/log4j/LevelTest.java index 9e5b0c7929..8ed550c17d 100644 --- a/tests/src/java/org/apache/log4j/LevelTest.java +++ b/tests/src/java/org/apache/log4j/LevelTest.java @@ -20,6 +20,7 @@ import junit.framework.TestCase; import org.apache.log4j.util.SerializationTestHelper; +import java.util.Locale; /** @@ -57,7 +58,13 @@ public void testDeserializeINFO() throws Exception { SerializationTestHelper.deserializeStream( "witness/serialization/info.bin"); assertTrue(obj instanceof Level); - assertTrue(obj == Level.INFO); + Level info = (Level) obj; + assertEquals("INFO", info.toString()); + // + // JDK 1.1 doesn't support readResolve necessary for the assertion + if (!System.getProperty("java.version").startsWith("1.1.")) { + assertTrue(obj == Level.INFO); + } } /** @@ -82,6 +89,7 @@ public void testCustomLevelSerialization() throws Exception { * serializable, but not resolved to a plain Level. */ private static class CustomLevel extends Level { + private static final long serialVersionUID = 1L; /** * Create an instance of CustomLevel. */ @@ -94,34 +102,34 @@ public CustomLevel() { /** * Tests Level.TRACE_INT. */ - public void testTraceInt() { - assertEquals(5000, Level.TRACE_INT); - } + public void testTraceInt() { + assertEquals(5000, Level.TRACE_INT); + } /** * Tests Level.TRACE. */ - public void testTrace() { - assertEquals("TRACE", Level.TRACE.toString()); - assertEquals(5000, Level.TRACE.toInt()); - assertEquals(7, Level.TRACE.getSyslogEquivalent()); - } + public void testTrace() { + assertEquals("TRACE", Level.TRACE.toString()); + assertEquals(5000, Level.TRACE.toInt()); + assertEquals(7, Level.TRACE.getSyslogEquivalent()); + } /** * Tests Level.toLevel(Level.TRACE_INT). */ - public void testIntToTrace() { - Level trace = Level.toLevel(5000); - assertEquals("TRACE", trace.toString()); - } + public void testIntToTrace() { + Level trace = Level.toLevel(5000); + assertEquals("TRACE", trace.toString()); + } /** * Tests Level.toLevel("TRACE"); */ - public void testStringToTrace() { - Level trace = Level.toLevel("TRACE"); - assertEquals("TRACE", trace.toString()); - } + public void testStringToTrace() { + Level trace = Level.toLevel("TRACE"); + assertEquals("TRACE", trace.toString()); + } /** * Tests that Level extends Priority. @@ -234,5 +242,26 @@ public void testToLevelNull() { assertEquals("FATAL", level.toString()); } + /** + * Test that dotless lower I + "nfo" is recognized as INFO. + */ + public void testDotlessLowerI() { + Level level = Level.toLevel("\u0131nfo"); + assertEquals("INFO", level.toString()); + } + + /** + * Test that dotted lower I + "nfo" is recognized as INFO + * even in Turkish locale. + */ + public void testDottedLowerI() { + Locale defaultLocale = Locale.getDefault(); + Locale turkey = new Locale("tr", "TR"); + Locale.setDefault(turkey); + Level level = Level.toLevel("info"); + Locale.setDefault(defaultLocale); + assertEquals("INFO", level.toString()); + } + } diff --git a/tests/src/java/org/apache/log4j/LogCapture.java b/tests/src/java/org/apache/log4j/LogCapture.java new file mode 100755 index 0000000000..032a02d42c --- /dev/null +++ b/tests/src/java/org/apache/log4j/LogCapture.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j; + +import junit.framework.Assert; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.log4j.VectorAppender; +import org.apache.log4j.spi.LoggingEvent; + +import java.util.Vector; + + +/** + * Helper class to set up and capture log messages. + */ +public class LogCapture { + /** + * Appender. + */ + private final VectorAppender appender; + + /** + * Expected level. + */ + private final Level level; + + /** + * Creates new instance of LogCapture. + * + */ + public LogCapture(final Level level) { + this.level = level; + + Logger root = Logger.getRootLogger(); + appender = new VectorAppender(); + root.addAppender(appender); + } + + /** + * Get message. + * @return rendered message, null if no logging event captured. + */ + public String getMessage() { + Vector vector = appender.getVector(); + String msg = null; + + switch (vector.size()) { + case 0: + break; + + case 1: + + LoggingEvent event = (LoggingEvent) vector.elementAt(0); + Assert.assertNotNull(event); + Assert.assertEquals(level, event.getLevel()); + msg = event.getRenderedMessage(); + + break; + + default: + Assert.fail("More than one request captured"); + } + + return msg; + } +} diff --git a/tests/src/java/org/apache/log4j/LogManagerTest.java b/tests/src/java/org/apache/log4j/LogManagerTest.java index 70f9c422e2..0319fda712 100644 --- a/tests/src/java/org/apache/log4j/LogManagerTest.java +++ b/tests/src/java/org/apache/log4j/LogManagerTest.java @@ -17,24 +17,15 @@ package org.apache.log4j; -import org.apache.log4j.spi.DefaultRepositorySelector; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.RepositorySelector; - import junit.framework.TestCase; /** - * Tests for {@link LogManager}. + * Tests for LogManager * * @author Curt Arnold - */ + **/ public class LogManagerTest extends TestCase { - - private static final Object sharedGuard = new Object(); - - private Hierarchy h = new Hierarchy(); - /** * Create new instance of LogManagerTest. * @param testName test name @@ -53,7 +44,6 @@ public void testDefaultConfigurationFile() { /** * Check value of DEFAULT_XML_CONFIGURATION_FILE. - * @deprecated since constant is deprecated */ public void testDefaultXmlConfigurationFile() { assertEquals("log4j.xml", LogManager.DEFAULT_XML_CONFIGURATION_FILE); @@ -82,33 +72,4 @@ public void testConfiguratorClassKey() { public void testDefaultInitOverrideKey() { assertEquals("log4j.defaultInitOverride", LogManager.DEFAULT_INIT_OVERRIDE_KEY); } - - public void testValidSelector() { - RepositorySelector selector = new DefaultRepositorySelector(h); - LogManager.setRepositorySelector(selector, sharedGuard); - Logger log = Logger.getLogger("TestValidSelector"); - log.info("Logger obtained"); - - try { - LogManager.setRepositorySelector(selector, "joe"); - fail("cannot cheat guard"); - } catch (IllegalArgumentException e) {} - } - - public void testInvalidSelector() { - try { - RepositorySelector selector = new RepositorySelector() { - - public LoggerRepository getLoggerRepository() { - return null; - } - - }; - LogManager.setRepositorySelector(selector, sharedGuard); - Logger.getLogger("TestInvalidSelector"); - fail("Invalid repository selector should have generated IllegalArgumentException"); - } catch (IllegalArgumentException iae) { - } - } - } diff --git a/tests/src/java/org/apache/log4j/LoggerTest.java b/tests/src/java/org/apache/log4j/LoggerTest.java deleted file mode 100644 index e567cd84b1..0000000000 --- a/tests/src/java/org/apache/log4j/LoggerTest.java +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j; - -import junit.framework.TestCase; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.RootLogger; - -import java.util.Enumeration; -import java.util.Locale; -import java.util.ResourceBundle; -import java.util.Vector; - - -/** - Used for internal unit testing the Logger class. - - @author Ceki Gülcü - -*/ -public class LoggerTest extends TestCase { - // A short message. - static String MSG = "M"; - Logger logger; - Appender a1; - Appender a2; - ResourceBundle rbUS; - ResourceBundle rbFR; - ResourceBundle rbCH; - - public LoggerTest(String name) { - super(name); - } - - public void setUp() { - rbUS = ResourceBundle.getBundle("L7D", new Locale("en", "US")); - assertNotNull(rbUS); - - rbFR = ResourceBundle.getBundle("L7D", new Locale("fr", "FR")); - assertNotNull("Got a null resource bundle.", rbFR); - - rbCH = ResourceBundle.getBundle("L7D", new Locale("fr", "CH")); - assertNotNull("Got a null resource bundle.", rbCH); - } - - public void tearDown() { - // Regular users should not use the clear method lightly! - //Logger.getDefaultHierarchy().clear(); - BasicConfigurator.resetConfiguration(); - a1 = null; - a2 = null; - } - - /** - Add an appender and see if it can be retrieved. - */ - public void testAppender1() { - logger = Logger.getLogger("test"); - a1 = new FileAppender(); - a1.setName("testAppender1"); - logger.addAppender(a1); - - Enumeration enumeration = logger.getAllAppenders(); - Appender aHat = (Appender) enumeration.nextElement(); - assertEquals(a1, aHat); - } - - /** - Add an appender X, Y, remove X and check if Y is the only - remaining appender. - */ - public void testAppender2() { - a1 = new FileAppender(); - a1.setName("testAppender2.1"); - a2 = new FileAppender(); - a2.setName("testAppender2.2"); - - logger = Logger.getLogger("test"); - logger.addAppender(a1); - logger.addAppender(a2); - logger.removeAppender("testAppender2.1"); - - Enumeration enumeration = logger.getAllAppenders(); - Appender aHat = (Appender) enumeration.nextElement(); - assertEquals(a2, aHat); - assertTrue(!enumeration.hasMoreElements()); - } - - /** - Test if logger a.b inherits its appender from a. - */ - public void testAdditivity1() { - Logger a = Logger.getLogger("a"); - Logger ab = Logger.getLogger("a.b"); - CountingAppender ca = new CountingAppender(); - ca.activateOptions(); - a.addAppender(ca); - - assertEquals(ca.counter, 0); - ab.debug(MSG); - assertEquals(ca.counter, 1); - ab.info(MSG); - assertEquals(ca.counter, 2); - ab.warn(MSG); - assertEquals(ca.counter, 3); - ab.error(MSG); - assertEquals(ca.counter, 4); - } - - /** - Test multiple additivity. - - */ - public void testAdditivity2() { - Logger a = Logger.getLogger("a"); - Logger ab = Logger.getLogger("a.b"); - Logger abc = Logger.getLogger("a.b.c"); - Logger x = Logger.getLogger("x"); - - CountingAppender ca1 = new CountingAppender(); - ca1.activateOptions(); - CountingAppender ca2 = new CountingAppender(); - ca2.activateOptions(); - a.addAppender(ca1); - abc.addAppender(ca2); - - assertEquals(ca1.counter, 0); - assertEquals(ca2.counter, 0); - - ab.debug(MSG); - assertEquals(ca1.counter, 1); - assertEquals(ca2.counter, 0); - - abc.debug(MSG); - assertEquals(ca1.counter, 2); - assertEquals(ca2.counter, 1); - - x.debug(MSG); - assertEquals(ca1.counter, 2); - assertEquals(ca2.counter, 1); - } - - /** - Test additivity flag. - - */ - public void testAdditivity3() { - Logger root = Logger.getRootLogger(); - Logger a = Logger.getLogger("a"); - Logger ab = Logger.getLogger("a.b"); - Logger abc = Logger.getLogger("a.b.c"); - Logger x = Logger.getLogger("x"); - - CountingAppender caRoot = new CountingAppender(); - caRoot.activateOptions(); - CountingAppender caA = new CountingAppender(); - caA.activateOptions(); - CountingAppender caABC = new CountingAppender(); - caABC.activateOptions(); - - root.addAppender(caRoot); - a.addAppender(caA); - abc.addAppender(caABC); - - assertEquals(caRoot.counter, 0); - assertEquals(caA.counter, 0); - assertEquals(caABC.counter, 0); - - ab.setAdditivity(false); - - a.debug(MSG); - assertEquals(caRoot.counter, 1); - assertEquals(caA.counter, 1); - assertEquals(caABC.counter, 0); - - ab.debug(MSG); - assertEquals(caRoot.counter, 1); - assertEquals(caA.counter, 1); - assertEquals(caABC.counter, 0); - - abc.debug(MSG); - assertEquals(caRoot.counter, 1); - assertEquals(caA.counter, 1); - assertEquals(caABC.counter, 1); - } - - public void testDisable1() { - CountingAppender caRoot = new CountingAppender(); - caRoot.activateOptions(); - Logger root = Logger.getRootLogger(); - root.addAppender(caRoot); - - LoggerRepository h = LogManager.getLoggerRepository(); - - //h.disableDebug(); - h.setThreshold((Level) Level.INFO); - assertEquals(caRoot.counter, 0); - - root.trace(MSG); - assertEquals(caRoot.counter, 0); - - root.debug(MSG); - assertEquals(caRoot.counter, 0); - - root.info(MSG); - assertEquals(caRoot.counter, 1); - root.log(Level.WARN, MSG); - assertEquals(caRoot.counter, 2); - root.warn(MSG); - assertEquals(caRoot.counter, 3); - - //h.disableInfo(); - h.setThreshold((Level) Level.WARN); - - root.trace(MSG); - assertEquals(caRoot.counter, 3); - - root.debug(MSG); - assertEquals(caRoot.counter, 3); - - root.info(MSG); - assertEquals(caRoot.counter, 3); - root.log(Level.WARN, MSG); - assertEquals(caRoot.counter, 4); - root.error(MSG); - assertEquals(caRoot.counter, 5); - root.log(Level.ERROR, MSG); - assertEquals(caRoot.counter, 6); - - //h.disableAll(); - h.setThreshold(Level.OFF); - - root.trace(MSG); - assertEquals(caRoot.counter, 6); - - root.debug(MSG); - assertEquals(caRoot.counter, 6); - - root.info(MSG); - assertEquals(caRoot.counter, 6); - root.log(Level.WARN, MSG); - assertEquals(caRoot.counter, 6); - root.error(MSG); - assertEquals(caRoot.counter, 6); - root.log(Level.FATAL, MSG); - assertEquals(caRoot.counter, 6); - root.log(Level.FATAL, MSG); - assertEquals(caRoot.counter, 6); - } - - public void testRB1() { - Logger root = Logger.getRootLogger(); - root.setResourceBundle(rbUS); - - ResourceBundle t = root.getResourceBundle(); - assertSame(t, rbUS); - - Logger x = Logger.getLogger("x"); - Logger x_y = Logger.getLogger("x.y"); - Logger x_y_z = Logger.getLogger("x.y.z"); - - t = x.getResourceBundle(); - assertSame(t, rbUS); - t = x_y.getResourceBundle(); - assertSame(t, rbUS); - t = x_y_z.getResourceBundle(); - assertSame(t, rbUS); - } - - public void testRB2() { - Logger root = Logger.getRootLogger(); - root.setResourceBundle(rbUS); - - ResourceBundle t = root.getResourceBundle(); - assertSame(t, rbUS); - - Logger x = Logger.getLogger("x"); - Logger x_y = Logger.getLogger("x.y"); - Logger x_y_z = Logger.getLogger("x.y.z"); - - x_y.setResourceBundle(rbFR); - t = x.getResourceBundle(); - assertSame(t, rbUS); - t = x_y.getResourceBundle(); - assertSame(t, rbFR); - t = x_y_z.getResourceBundle(); - assertSame(t, rbFR); - } - - public void testRB3() { - Logger root = Logger.getRootLogger(); - root.setResourceBundle(rbUS); - - ResourceBundle t = root.getResourceBundle(); - assertSame(t, rbUS); - - Logger x = Logger.getLogger("x"); - Logger x_y = Logger.getLogger("x.y"); - Logger x_y_z = Logger.getLogger("x.y.z"); - - x_y.setResourceBundle(rbFR); - x_y_z.setResourceBundle(rbCH); - t = x.getResourceBundle(); - assertSame(t, rbUS); - t = x_y.getResourceBundle(); - assertSame(t, rbFR); - t = x_y_z.getResourceBundle(); - assertSame(t, rbCH); - } - - public void testExists() { - Logger a = Logger.getLogger("a"); - Logger a_b = Logger.getLogger("a.b"); - Logger a_b_c = Logger.getLogger("a.b.c"); - - Logger t; - t = LogManager.exists("xx"); - assertNull(t); - t = LogManager.exists("a"); - assertSame(a, t); - t = LogManager.exists("a.b"); - assertSame(a_b, t); - t = LogManager.exists("a.b.c"); - assertSame(a_b_c, t); - } - - public void testHierarchy1() { - Hierarchy h = new Hierarchy(new RootLogger((Level) Level.ERROR)); - Logger a0 = h.getLogger("a"); - assertEquals("a", a0.getName()); - assertNull(a0.getLevel()); - assertSame(Level.ERROR, a0.getEffectiveLevel()); - - Logger a1 = h.getLogger("a"); - assertSame(a0, a1); - } - - - /** - * Tests logger.trace(Object). - * @since 1.2.12 - */ - public void testTrace() { - VectorAppender appender = new VectorAppender(); - appender.activateOptions(); - Logger root = Logger.getRootLogger(); - root.addAppender(appender); - root.setLevel(Level.INFO); - - Logger tracer = Logger.getLogger("com.example.Tracer"); - tracer.setLevel(Level.TRACE); - - tracer.trace("Message 1"); - root.trace("Discarded Message"); - root.trace("Discarded Message"); - - Vector msgs = appender.getVector(); - assertEquals(1, msgs.size()); - LoggingEvent event = (LoggingEvent) msgs.get(0); - assertEquals(Level.TRACE, event.getLevel()); - assertEquals("Message 1", event.getMessage()); - } - - /** - * Tests logger.trace(Object, Exception). - * @since 1.2.12 - */ - public void testTraceWithException() { - VectorAppender appender = new VectorAppender(); - appender.activateOptions(); - Logger root = Logger.getRootLogger(); - root.addAppender(appender); - root.setLevel(Level.INFO); - - Logger tracer = Logger.getLogger("com.example.Tracer"); - tracer.setLevel(Level.TRACE); - NullPointerException ex = new NullPointerException(); - - tracer.trace("Message 1", ex); - root.trace("Discarded Message", ex); - root.trace("Discarded Message", ex); - - Vector msgs = appender.getVector(); - assertEquals(1, msgs.size()); - LoggingEvent event = (LoggingEvent) msgs.get(0); - assertEquals(Level.TRACE, event.getLevel()); - assertEquals("Message 1", event.getMessage()); - } - - /** - * Tests isTraceEnabled. - * @since 1.2.12 - */ - public void testIsTraceEnabled() { - VectorAppender appender = new VectorAppender(); - appender.activateOptions(); - Logger root = Logger.getRootLogger(); - root.addAppender(appender); - root.setLevel(Level.INFO); - - Logger tracer = Logger.getLogger("com.example.Tracer"); - tracer.setLevel(Level.TRACE); - - assertTrue(tracer.isTraceEnabled()); - assertFalse(root.isTraceEnabled()); - } - - private static class CountingAppender extends AppenderSkeleton { - int counter; - - CountingAppender() { - super(true); - counter = 0; - } - - public void close() { - } - - public void append(LoggingEvent event) { - counter++; - } - - /** - * Gets whether appender requires a layout. - * @return false - */ - public boolean requiresLayout() { - return false; - } - - } -} - -// End of class: LoggerTestCase.java diff --git a/tests/src/java/org/apache/log4j/LoggerTestCase.java b/tests/src/java/org/apache/log4j/LoggerTestCase.java new file mode 100644 index 0000000000..e2e15a217f --- /dev/null +++ b/tests/src/java/org/apache/log4j/LoggerTestCase.java @@ -0,0 +1,499 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j; + +import junit.framework.TestCase; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.spi.RootLogger; +import org.apache.log4j.spi.LoggerRepository; +import org.apache.log4j.spi.HierarchyEventListener; + +import java.util.Enumeration; +import java.util.Locale; +import java.util.ResourceBundle; +import java.util.Vector; + +/** + Used for internal unit testing the Logger class. + + @author Ceki Gülcü + +*/ +public class LoggerTestCase extends TestCase { + + Logger logger; + Appender a1; + Appender a2; + + ResourceBundle rbUS; + ResourceBundle rbFR; + ResourceBundle rbCH; + + // A short message. + static String MSG = "M"; + + + public LoggerTestCase(String name) { + super(name); + } + + public + void setUp() { + rbUS = ResourceBundle.getBundle("L7D", new Locale("en", "US")); + assertNotNull(rbUS); + + rbFR = ResourceBundle.getBundle("L7D", new Locale("fr", "FR")); + assertNotNull("Got a null resource bundle.", rbFR); + + rbCH = ResourceBundle.getBundle("L7D", new Locale("fr", "CH")); + assertNotNull("Got a null resource bundle.", rbCH); + + } + + public + void tearDown() { + // Regular users should not use the clear method lightly! + //Logger.getDefaultHierarchy().clear(); + BasicConfigurator.resetConfiguration(); + a1 = null; + a2 = null; + } + + /** + Add an appender and see if it can be retrieved. + */ + public + void testAppender1() { + logger = Logger.getLogger("test"); + a1 = new FileAppender(); + a1.setName("testAppender1"); + logger.addAppender(a1); + + Enumeration enumeration = logger.getAllAppenders(); + Appender aHat = (Appender) enumeration.nextElement(); + assertEquals(a1, aHat); + } + + /** + Add an appender X, Y, remove X and check if Y is the only + remaining appender. + */ + public + void testAppender2() { + a1 = new FileAppender(); + a1.setName("testAppender2.1"); + a2 = new FileAppender(); + a2.setName("testAppender2.2"); + + logger = Logger.getLogger("test"); + logger.addAppender(a1); + logger.addAppender(a2); + logger.removeAppender("testAppender2.1"); + Enumeration enumeration = logger.getAllAppenders(); + Appender aHat = (Appender) enumeration.nextElement(); + assertEquals(a2, aHat); + assertTrue(!enumeration.hasMoreElements()); + } + + /** + Test if logger a.b inherits its appender from a. + */ + public + void testAdditivity1() { + Logger a = Logger.getLogger("a"); + Logger ab = Logger.getLogger("a.b"); + CountingAppender ca = new CountingAppender(); + a.addAppender(ca); + + assertEquals(ca.counter, 0); + ab.debug(MSG); assertEquals(ca.counter, 1); + ab.info(MSG); assertEquals(ca.counter, 2); + ab.warn(MSG); assertEquals(ca.counter, 3); + ab.error(MSG); assertEquals(ca.counter, 4); + + + } + + /** + Test multiple additivity. + + */ + public + void testAdditivity2() { + + Logger a = Logger.getLogger("a"); + Logger ab = Logger.getLogger("a.b"); + Logger abc = Logger.getLogger("a.b.c"); + Logger x = Logger.getLogger("x"); + + CountingAppender ca1 = new CountingAppender(); + CountingAppender ca2 = new CountingAppender(); + + a.addAppender(ca1); + abc.addAppender(ca2); + + assertEquals(ca1.counter, 0); + assertEquals(ca2.counter, 0); + + ab.debug(MSG); + assertEquals(ca1.counter, 1); + assertEquals(ca2.counter, 0); + + abc.debug(MSG); + assertEquals(ca1.counter, 2); + assertEquals(ca2.counter, 1); + + x.debug(MSG); + assertEquals(ca1.counter, 2); + assertEquals(ca2.counter, 1); + } + + /** + Test additivity flag. + + */ + public + void testAdditivity3() { + + Logger root = Logger.getRootLogger(); + Logger a = Logger.getLogger("a"); + Logger ab = Logger.getLogger("a.b"); + Logger abc = Logger.getLogger("a.b.c"); + + CountingAppender caRoot = new CountingAppender(); + CountingAppender caA = new CountingAppender(); + CountingAppender caABC = new CountingAppender(); + + root.addAppender(caRoot); + a.addAppender(caA); + abc.addAppender(caABC); + + assertEquals(caRoot.counter, 0); + assertEquals(caA.counter, 0); + assertEquals(caABC.counter, 0); + + ab.setAdditivity(false); + + + a.debug(MSG); + assertEquals(caRoot.counter, 1); + assertEquals(caA.counter, 1); + assertEquals(caABC.counter, 0); + + ab.debug(MSG); + assertEquals(caRoot.counter, 1); + assertEquals(caA.counter, 1); + assertEquals(caABC.counter, 0); + + abc.debug(MSG); + assertEquals(caRoot.counter, 1); + assertEquals(caA.counter, 1); + assertEquals(caABC.counter, 1); + + } + + + public + void testDisable1() { + CountingAppender caRoot = new CountingAppender(); + Logger root = Logger.getRootLogger(); + root.addAppender(caRoot); + + LoggerRepository h = LogManager.getLoggerRepository(); + //h.disableDebug(); + h.setThreshold(Level.INFO); + assertEquals(caRoot.counter, 0); + + root.debug(MSG); assertEquals(caRoot.counter, 0); + root.info(MSG); assertEquals(caRoot.counter, 1); + root.log(Level.WARN, MSG); assertEquals(caRoot.counter, 2); + root.warn(MSG); assertEquals(caRoot.counter, 3); + + //h.disableInfo(); + h.setThreshold(Level.WARN); + root.debug(MSG); assertEquals(caRoot.counter, 3); + root.info(MSG); assertEquals(caRoot.counter, 3); + root.log(Level.WARN, MSG); assertEquals(caRoot.counter, 4); + root.error(MSG); assertEquals(caRoot.counter, 5); + root.log(Level.ERROR, MSG); assertEquals(caRoot.counter, 6); + + //h.disableAll(); + h.setThreshold(Level.OFF); + root.debug(MSG); assertEquals(caRoot.counter, 6); + root.info(MSG); assertEquals(caRoot.counter, 6); + root.log(Level.WARN, MSG); assertEquals(caRoot.counter, 6); + root.error(MSG); assertEquals(caRoot.counter, 6); + root.log(Level.FATAL, MSG); assertEquals(caRoot.counter, 6); + root.log(Level.FATAL, MSG); assertEquals(caRoot.counter, 6); + + //h.disable(Level.FATAL); + h.setThreshold(Level.OFF); + root.debug(MSG); assertEquals(caRoot.counter, 6); + root.info(MSG); assertEquals(caRoot.counter, 6); + root.log(Level.WARN, MSG); assertEquals(caRoot.counter, 6); + root.error(MSG); assertEquals(caRoot.counter, 6); + root.log(Level.ERROR, MSG); assertEquals(caRoot.counter, 6); + root.log(Level.FATAL, MSG); assertEquals(caRoot.counter, 6); + } + + + public + void testRB1() { + Logger root = Logger.getRootLogger(); + root.setResourceBundle(rbUS); + ResourceBundle t = root.getResourceBundle(); + assertSame(t, rbUS); + + Logger x = Logger.getLogger("x"); + Logger x_y = Logger.getLogger("x.y"); + Logger x_y_z = Logger.getLogger("x.y.z"); + + t = x.getResourceBundle(); assertSame(t, rbUS); + t = x_y.getResourceBundle(); assertSame(t, rbUS); + t = x_y_z.getResourceBundle(); assertSame(t, rbUS); + } + + public + void testRB2() { + Logger root = Logger.getRootLogger(); + root.setResourceBundle(rbUS); + ResourceBundle t = root.getResourceBundle(); + assertSame(t, rbUS); + + Logger x = Logger.getLogger("x"); + Logger x_y = Logger.getLogger("x.y"); + Logger x_y_z = Logger.getLogger("x.y.z"); + + x_y.setResourceBundle(rbFR); + t = x.getResourceBundle(); assertSame(t, rbUS); + t = x_y.getResourceBundle(); assertSame(t, rbFR); + t = x_y_z.getResourceBundle(); assertSame(t, rbFR); + } + + + public + void testRB3() { + Logger root = Logger.getRootLogger(); + root.setResourceBundle(rbUS); + ResourceBundle t = root.getResourceBundle(); + assertSame(t, rbUS); + + Logger x = Logger.getLogger("x"); + Logger x_y = Logger.getLogger("x.y"); + Logger x_y_z = Logger.getLogger("x.y.z"); + + x_y.setResourceBundle(rbFR); + x_y_z.setResourceBundle(rbCH); + t = x.getResourceBundle(); assertSame(t, rbUS); + t = x_y.getResourceBundle(); assertSame(t, rbFR); + t = x_y_z.getResourceBundle(); assertSame(t, rbCH); + } + + public + void testExists() { + Logger a = Logger.getLogger("a"); + Logger a_b = Logger.getLogger("a.b"); + Logger a_b_c = Logger.getLogger("a.b.c"); + + Logger t; + t = LogManager.exists("xx"); assertNull(t); + t = LogManager.exists("a"); assertSame(a, t); + t = LogManager.exists("a.b"); assertSame(a_b, t); + t = LogManager.exists("a.b.c"); assertSame(a_b_c, t); + } + + public + void testHierarchy1() { + Hierarchy h = new Hierarchy(new RootLogger(Level.ERROR)); + Logger a0 = h.getLogger("a"); + assertEquals("a", a0.getName()); + assertNull(a0.getLevel()); + assertSame(Level.ERROR, a0.getEffectiveLevel()); + + Logger a1 = h.getLogger("a"); + assertSame(a0, a1); + } + + /** + * Tests logger.trace(Object). + * @since 1.2.12 + */ + public void testTrace() { + VectorAppender appender = new VectorAppender(); + appender.activateOptions(); + Logger root = Logger.getRootLogger(); + root.addAppender(appender); + root.setLevel(Level.INFO); + + Logger tracer = Logger.getLogger("com.example.Tracer"); + tracer.setLevel(Level.TRACE); + + tracer.trace("Message 1"); + root.trace("Discarded Message"); + root.trace("Discarded Message"); + + Vector msgs = appender.getVector(); + assertEquals(1, msgs.size()); + LoggingEvent event = (LoggingEvent) msgs.elementAt(0); + assertEquals(Level.TRACE, event.getLevel()); + assertEquals("Message 1", event.getMessage()); + } + + /** + * Tests logger.trace(Object, Exception). + * @since 1.2.12 + */ + public void testTraceWithException() { + VectorAppender appender = new VectorAppender(); + appender.activateOptions(); + Logger root = Logger.getRootLogger(); + root.addAppender(appender); + root.setLevel(Level.INFO); + + Logger tracer = Logger.getLogger("com.example.Tracer"); + tracer.setLevel(Level.TRACE); + NullPointerException ex = new NullPointerException(); + + tracer.trace("Message 1", ex); + root.trace("Discarded Message", ex); + root.trace("Discarded Message", ex); + + Vector msgs = appender.getVector(); + assertEquals(1, msgs.size()); + LoggingEvent event = (LoggingEvent) msgs.elementAt(0); + assertEquals(Level.TRACE, event.getLevel()); + assertEquals("Message 1", event.getMessage()); + } + + /** + * Tests isTraceEnabled. + * @since 1.2.12 + */ + public void testIsTraceEnabled() { + VectorAppender appender = new VectorAppender(); + appender.activateOptions(); + Logger root = Logger.getRootLogger(); + root.addAppender(appender); + root.setLevel(Level.INFO); + + Logger tracer = Logger.getLogger("com.example.Tracer"); + tracer.setLevel(Level.TRACE); + + assertTrue(tracer.isTraceEnabled()); + assertFalse(root.isTraceEnabled()); + } + + private static final class CountingHierarchyEventListener implements HierarchyEventListener { + private int addEventCount; + private int removeEventCount; + + public CountingHierarchyEventListener() { + addEventCount = removeEventCount = 0; + } + public void addAppenderEvent(Category cat, Appender appender) { + addEventCount++; + } + + public void removeAppenderEvent(Category cat, Appender appender) { + removeEventCount++; + } + + public int getAddEventCount() { + return addEventCount; + } + public int getRemoveEventCount() { + return removeEventCount; + } + } + + + public void testAppenderEvent1() { + CountingHierarchyEventListener listener = new CountingHierarchyEventListener(); + LogManager.getLoggerRepository().addHierarchyEventListener(listener); + CountingAppender appender = new CountingAppender(); + Logger root = Logger.getRootLogger(); + root.addAppender(appender); + assertEquals(1, listener.getAddEventCount()); + assertEquals(0, listener.getRemoveEventCount()); + root.removeAppender(appender); + assertEquals(1, listener.getAddEventCount()); + assertEquals(1, listener.getRemoveEventCount()); + } + + public void testAppenderEvent2() { + CountingHierarchyEventListener listener = new CountingHierarchyEventListener(); + LogManager.getLoggerRepository().addHierarchyEventListener(listener); + CountingAppender appender = new CountingAppender(); + appender.setName("A1"); + Logger root = Logger.getRootLogger(); + root.addAppender(appender); + assertEquals(1, listener.getAddEventCount()); + assertEquals(0, listener.getRemoveEventCount()); + root.removeAppender(appender.getName()); + assertEquals(1, listener.getAddEventCount()); + assertEquals(1, listener.getRemoveEventCount()); + } + + public void testAppenderEvent3() { + CountingHierarchyEventListener listener = new CountingHierarchyEventListener(); + LogManager.getLoggerRepository().addHierarchyEventListener(listener); + CountingAppender appender = new CountingAppender(); + Logger root = Logger.getRootLogger(); + root.addAppender(appender); + assertEquals(1, listener.getAddEventCount()); + assertEquals(0, listener.getRemoveEventCount()); + root.removeAllAppenders(); + assertEquals(1, listener.getAddEventCount()); + assertEquals(1, listener.getRemoveEventCount()); + } + + + public void testAppenderEvent4() { + CountingHierarchyEventListener listener = new CountingHierarchyEventListener(); + LogManager.getLoggerRepository().addHierarchyEventListener(listener); + CountingAppender appender = new CountingAppender(); + Logger root = Logger.getRootLogger(); + root.addAppender(appender); + assertEquals(1, listener.getAddEventCount()); + assertEquals(0, listener.getRemoveEventCount()); + LogManager.resetConfiguration(); + assertEquals(1, listener.getAddEventCount()); + assertEquals(1, listener.getRemoveEventCount()); + } + + static private class CountingAppender extends AppenderSkeleton { + + int counter; + + CountingAppender() { + counter = 0; + } + public void close() { + } + + public + void append(LoggingEvent event) { + counter++; + } + + public + boolean requiresLayout() { + return true; + } + } +} diff --git a/tests/src/java/org/apache/log4j/MDCOrderFilter.java b/tests/src/java/org/apache/log4j/MDCOrderFilter.java new file mode 100644 index 0000000000..06f85b28b9 --- /dev/null +++ b/tests/src/java/org/apache/log4j/MDCOrderFilter.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j; + +import org.apache.log4j.util.Filter; + +/** + * This class switches MDC values into the order + * (unreasonably) expected by the witness files. + */ +public class MDCOrderFilter implements Filter { + + /** + * Unexpected orders of keys. + * Note expected values are "va-one-one" and "va-one-two". + */ + private static final String[] patterns = + new String[] { + "{key2,va12}{key1,va11}", + "{key2,value2}{key1,value1}" + }; + + /** + * Replacement values. + */ + private static final String[] replacements = + new String[] { + "{key1,va11}{key2,va12}", + "{key1,value1}{key2,value2}" + }; + + /** + * Switch order of MDC keys when not in expected order. + */ + public String filter(final String in) { + if (in == null) { + return null; + } + + for(int i = 0; i < patterns.length; i++) { + int ipos = in.indexOf(patterns[i]); + if (ipos >= 1) { + return in.substring(0, ipos) + + replacements[i] + + in.substring(ipos + patterns[i].length()); + } + } + return in; + } +} diff --git a/tests/src/java/org/apache/log4j/MDCTestCase.java b/tests/src/java/org/apache/log4j/MDCTestCase.java new file mode 100644 index 0000000000..d340696f51 --- /dev/null +++ b/tests/src/java/org/apache/log4j/MDCTestCase.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j; + +import java.lang.ref.Reference; +import java.lang.reflect.Field; +import junit.framework.TestCase; + +/** + * Test for MDC + * + * @author Maarten Bosteels + */ +public class MDCTestCase extends TestCase { + + public void setUp() { + MDC.clear(); + } + + public void tearDown() { + MDC.clear(); + } + + public void testPut() throws Exception { + MDC.put("key", "some value"); + assertEquals("some value", MDC.get("key")); + assertEquals(1, MDC.getContext().size()); + } + + public void testRemoveLastKey() throws Exception { + MDC.put("key", "some value"); + + MDC.remove("key"); + checkThreadLocalsForLeaks(); + } + + private void checkThreadLocalsForLeaks() throws Exception { + + // this code is heavily based on code in org.apache.catalina.loader.WebappClassLoader + + // Make the fields in the Thread class that store ThreadLocals accessible + Field threadLocalsField = Thread.class.getDeclaredField("threadLocals"); + threadLocalsField.setAccessible(true); + Field inheritableThreadLocalsField = Thread.class.getDeclaredField("inheritableThreadLocals"); + inheritableThreadLocalsField.setAccessible(true); + // Make the underlying array of ThreadLoad.ThreadLocalMap.Entry objects accessible + Class tlmClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); + Field tableField = tlmClass.getDeclaredField("table"); + tableField.setAccessible(true); + + Thread thread = Thread.currentThread(); + + Object threadLocalMap; + threadLocalMap = threadLocalsField.get(thread); + // Check the first map + checkThreadLocalMapForLeaks(threadLocalMap, tableField); + // Check the second map + threadLocalMap = inheritableThreadLocalsField.get(thread); + checkThreadLocalMapForLeaks(threadLocalMap, tableField); + + } + + private void checkThreadLocalMapForLeaks(Object map, Field internalTableField) + throws IllegalAccessException, NoSuchFieldException { + if (map != null) { + Object[] table = (Object[]) internalTableField.get(map); + if (table != null) { + for (int j =0; j < table.length; j++) { + if (table[j] != null) { + + // Check the key + Object key = ((Reference) table[j]).get(); + String keyClassName = key.getClass().getName(); + + if (key.getClass() == org.apache.log4j.helpers.ThreadLocalMap.class) { + fail("Found a ThreadLocal with key of type [" + keyClassName + "]"); + } + } + } + } + } + } +} diff --git a/tests/src/java/org/apache/log4j/MinimumTest.java b/tests/src/java/org/apache/log4j/MinimumTest.java deleted file mode 100644 index ee522f1736..0000000000 --- a/tests/src/java/org/apache/log4j/MinimumTest.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.apache.log4j.helpers.Constants; -import org.apache.log4j.util.*; - - -/** - A superficial but general test of log4j. - */ -public class MinimumTest extends TestCase { - static String FILTERED = "output/filtered"; - static String EXCEPTION1 = "java.lang.Exception: Just testing"; - static String EXCEPTION2 = "\\s*at .*\\(.*:\\d{1,4}\\)"; - static String EXCEPTION3 = "\\s*at .*\\(Native Method\\)"; - - //18 fevr. 2002 20:02:41,551 [main] FATAL ERR - Message 0 - static String TTCC_PAT = - Filter.ABSOLUTE_DATE_AND_TIME_PAT - + " \\[main]\\ (DEBUG|INFO|WARN|ERROR|FATAL) .* - Message \\d{1,2}"; - static String TTCC2_PAT = - Filter.ABSOLUTE_DATE_AND_TIME_PAT - + " \\[main]\\ (DEBUG|INFO|WARN|ERROR|FATAL) .* - Messages should bear numbers 0 through 23\\."; - - //18 fvr. 2002 19:49:53,456 - Logger root; - Logger logger; - - public MinimumTest(String name) { - super(name); - } - - public void setUp() { - root = Logger.getRootLogger(); - root.removeAllAppenders(); - } - - public void tearDown() { - root.getLoggerRepository().resetConfiguration(); - } - - public void simple() throws Exception { - Layout layout = new SimpleLayout(); - Appender appender = new FileAppender(layout, "output/simple", false); - root.addAppender(appender); - common(); - - Transformer.transform( - "output/simple", FILTERED, - new Filter[] { new LineNumberFilter(), new SunReflectFilter(), - new JunitTestRunnerFilter() }); - - assertTrue(Compare.compare(FILTERED, "witness/simple")); - } - - /** - * Tests deprecated TTCCLayout. - * - * @deprecated Class under test is deprecated. - * @throws Exception if io exception. - */ - public void ttcc() throws Exception { - TTCCLayout layout = new TTCCLayout(); - layout.setDateFormat(Constants.DATE_AND_TIME_FORMAT); - layout.activateOptions(); - - Appender appender = new FileAppender(layout, "output/ttcc", false); - root.addAppender(appender); - common(); - - ControlFilter cf1 = - new ControlFilter( - new String[] { TTCC_PAT, TTCC2_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); - - Transformer.transform( - "output/ttcc", FILTERED, - new Filter[] { - cf1, new LineNumberFilter(), new AbsoluteDateAndTimeFilter(), - new SunReflectFilter(), new JunitTestRunnerFilter() - }); - - assertTrue(Compare.compare(FILTERED, "witness/ttcc")); - } - - void common() { - int i = 0; - - // In the lines below, the category names are chosen as an aid in - // remembering their level values. In general, the category names - // have no bearing to level values. - Logger ERR = Logger.getLogger("ERR"); - ERR.setLevel(Level.ERROR); - - Logger INF = Logger.getLogger("INF"); - INF.setLevel(Level.INFO); - - Logger INF_ERR = Logger.getLogger("INF.ERR"); - INF_ERR.setLevel(Level.ERROR); - - Logger DEB = Logger.getLogger("DEB"); - DEB.setLevel(Level.DEBUG); - - // Note: categories with undefined level - Logger INF_UNDEF = Logger.getLogger("INF.UNDEF"); - Logger INF_ERR_UNDEF = Logger.getLogger("INF.ERR.UNDEF"); - Logger UNDEF = Logger.getLogger("UNDEF"); - - // These should all log.---------------------------- - ERR.log(Level.FATAL, "Message " + i); - i++; //0 - ERR.error("Message " + i); - i++; - - INF.log(Level.FATAL, "Message " + i); - i++; // 2 - INF.error("Message " + i); - i++; - INF.warn("Message " + i); - i++; - INF.info("Message " + i); - i++; - - INF_UNDEF.log(Level.FATAL, "Message " + i); - i++; //6 - INF_UNDEF.error("Message " + i); - i++; - INF_UNDEF.warn("Message " + i); - i++; - INF_UNDEF.info("Message " + i); - i++; - - INF_ERR.log(Level.FATAL, "Message " + i); - i++; // 10 - INF_ERR.error("Message " + i); - i++; - - INF_ERR_UNDEF.log(Level.FATAL, "Message " + i); - i++; - INF_ERR_UNDEF.error("Message " + i); - i++; - - DEB.log(Level.FATAL, "Message " + i); - i++; //14 - DEB.error("Message " + i); - i++; - DEB.warn("Message " + i); - i++; - DEB.info("Message " + i); - i++; - DEB.debug("Message " + i); - i++; - - // defaultLevel=DEBUG - UNDEF.log(Level.FATAL, "Message " + i); - i++; // 19 - UNDEF.error("Message " + i); - i++; - UNDEF.warn("Message " + i); - i++; - UNDEF.info("Message " + i); - i++; - UNDEF.debug("Message " + i, new Exception("Just testing.")); - i++; - - // ------------------------------------------------- - // The following should not log - ERR.warn("Message " + i); - i++; - ERR.info("Message " + i); - i++; - ERR.debug("Message " + i); - i++; - - INF.debug("Message " + i); - i++; - INF_UNDEF.debug("Message " + i); - i++; - - INF_ERR.warn("Message " + i); - i++; - INF_ERR.info("Message " + i); - i++; - INF_ERR.debug("Message " + i); - i++; - INF_ERR_UNDEF.warn("Message " + i); - i++; - INF_ERR_UNDEF.info("Message " + i); - i++; - INF_ERR_UNDEF.debug("Message " + i); - i++; - - // ------------------------------------------------- - INF.info("Messages should bear numbers 0 through 23."); - } - - public static Test suite() { - TestSuite suite = new TestSuite(); - suite.addTest(new MinimumTest("simple")); - suite.addTest(new MinimumTest("ttcc")); - - return suite; - } -} diff --git a/tests/src/java/org/apache/log4j/MinimumTestCase.java b/tests/src/java/org/apache/log4j/MinimumTestCase.java new file mode 100644 index 0000000000..50d1503f7b --- /dev/null +++ b/tests/src/java/org/apache/log4j/MinimumTestCase.java @@ -0,0 +1,205 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j; + +import junit.framework.TestCase; +import junit.framework.TestSuite; +import junit.framework.Test; + +import org.apache.log4j.helpers.AbsoluteTimeDateFormat; +import org.apache.log4j.util.*; + +/** + A superficial but general test of log4j. + */ +public class MinimumTestCase extends TestCase { + + static String FILTERED = "output/filtered"; + + static String EXCEPTION1 = "java.lang.Exception: Just testing"; + static String EXCEPTION2 = "\\s*at .*\\(.*\\)"; + static String EXCEPTION3 = "\\s*at .*\\(Native Method\\)"; + static String EXCEPTION4 = "\\s*at .*\\(.*Compiled Code\\)"; + static String EXCEPTION5 = "\\s*at .*\\(.*libgcj.*\\)"; + + //18 fevr. 2002 20:02:41,551 [main] FATAL ERR - Message 0 + + static String TTCC_PAT = Filter.ABSOLUTE_DATE_AND_TIME_PAT+ + " \\[main]\\ (TRACE|DEBUG|INFO|WARN|ERROR|FATAL) .* - Message \\d{1,2}"; + + static String TTCC2_PAT = Filter.ABSOLUTE_DATE_AND_TIME_PAT+ + " \\[main]\\ (TRACE|DEBUG|INFO|WARN|ERROR|FATAL) .* - Messages should bear numbers 0 through 29\\."; + + //18 fvr. 2002 19:49:53,456 + + Logger root; + Logger logger; + + public MinimumTestCase(String name) { + super(name); + } + + public void setUp() { + root = Logger.getRootLogger(); + root.removeAllAppenders(); + } + + public void tearDown() { + root.getLoggerRepository().resetConfiguration(); + } + + public void simple() throws Exception { + + Layout layout = new SimpleLayout(); + Appender appender = new FileAppender(layout, "output/simple", false); + root.addAppender(appender); + common(); + + Transformer.transform( + "output/simple", FILTERED, + new Filter[] { new LineNumberFilter(), + new SunReflectFilter(), + new JunitTestRunnerFilter() }); + assertTrue(Compare.compare(FILTERED, "witness/simple")); + } + + public void ttcc() throws Exception { + + Layout layout = new TTCCLayout(AbsoluteTimeDateFormat.DATE_AND_TIME_DATE_FORMAT); + Appender appender = new FileAppender(layout, "output/ttcc", false); + root.addAppender(appender); + + String oldName = Thread.currentThread().getName(); + Thread.currentThread().setName("main"); + common(); + Thread.currentThread().setName(oldName); + + ControlFilter cf1 = new ControlFilter(new String[]{TTCC_PAT, + TTCC2_PAT, EXCEPTION1, EXCEPTION2, + EXCEPTION3, EXCEPTION4, EXCEPTION5 }); + + Transformer.transform( + "output/ttcc", FILTERED, + new Filter[] { + cf1, new LineNumberFilter(), + new AbsoluteDateAndTimeFilter(), + new SunReflectFilter(), new JunitTestRunnerFilter() + }); + + assertTrue(Compare.compare(FILTERED, "witness/ttcc")); + } + + + void common() { + + int i = 0; + + // In the lines below, the category names are chosen as an aid in + // remembering their level values. In general, the category names + // have no bearing to level values. + + Logger ERR = Logger.getLogger("ERR"); + ERR.setLevel(Level.ERROR); + Logger INF = Logger.getLogger("INF"); + INF.setLevel(Level.INFO); + Logger INF_ERR = Logger.getLogger("INF.ERR"); + INF_ERR.setLevel(Level.ERROR); + Logger DEB = Logger.getLogger("DEB"); + DEB.setLevel(Level.DEBUG); + Logger TRC = Logger.getLogger("TRC"); + TRC.setLevel(Level.TRACE); + + // Note: categories with undefined level + Logger INF_UNDEF = Logger.getLogger("INF.UNDEF"); + Logger INF_ERR_UNDEF = Logger.getLogger("INF.ERR.UNDEF"); + Logger UNDEF = Logger.getLogger("UNDEF"); + + + // These should all log.---------------------------- + ERR.log(Level.FATAL, "Message " + i); i++; //0 + ERR.error( "Message " + i); i++; + + INF.log(Level.FATAL, "Message " + i); i++; // 2 + INF.error( "Message " + i); i++; + INF.warn ( "Message " + i); i++; + INF.info ( "Message " + i); i++; + + INF_UNDEF.log(Level.FATAL, "Message " + i); i++; //6 + INF_UNDEF.error( "Message " + i); i++; + INF_UNDEF.warn ( "Message " + i); i++; + INF_UNDEF.info ( "Message " + i); i++; + + INF_ERR.log(Level.FATAL, "Message " + i); i++; // 10 + INF_ERR.error( "Message " + i); i++; + + INF_ERR_UNDEF.log(Level.FATAL, "Message " + i); i++; + INF_ERR_UNDEF.error( "Message " + i); i++; + + DEB.log(Level.FATAL, "Message " + i); i++; //14 + DEB.error( "Message " + i); i++; + DEB.warn ( "Message " + i); i++; + DEB.info ( "Message " + i); i++; + DEB.debug( "Message " + i); i++; + + TRC.log(Level.FATAL, "Message " + i); i++; //19 + TRC.error( "Message " + i); i++; + TRC.warn ( "Message " + i); i++; + TRC.info ( "Message " + i); i++; + TRC.debug( "Message " + i); i++; + TRC.trace( "Message " + i); i++; + + // defaultLevel=DEBUG + UNDEF.log(Level.FATAL, "Message " + i); i++; // 25 + UNDEF.error("Message " + i); i++; + UNDEF.warn ("Message " + i); i++; + UNDEF.info ("Message " + i); i++; + UNDEF.debug("Message " + i, new Exception("Just testing.")); + int printCount = i; + i++; + + // ------------------------------------------------- + // The following should not log + ERR.warn("Message " + i); i++; + ERR.info("Message " + i); i++; + ERR.debug("Message " + i); i++; + + INF.debug("Message " + i); i++; + INF_UNDEF.debug("Message " + i); i++; + + + INF_ERR.warn("Message " + i); i++; + INF_ERR.info("Message " + i); i++; + INF_ERR.debug("Message " + i); i++; + INF_ERR_UNDEF.warn("Message " + i); i++; + INF_ERR_UNDEF.info("Message " + i); i++; + INF_ERR_UNDEF.debug("Message " + i); i++; + + UNDEF.trace("Message " + i, new Exception("Just testing.")); i++; + // ------------------------------------------------- + + INF.info("Messages should bear numbers 0 through "+printCount+"."); + } + + public static Test suite() { + TestSuite suite = new TestSuite(); + suite.addTest(new MinimumTestCase("simple")); + suite.addTest(new MinimumTestCase("ttcc")); + return suite; + } + +} diff --git a/tests/src/java/org/apache/log4j/MyPatternLayout.java b/tests/src/java/org/apache/log4j/MyPatternLayout.java index f004d9e04a..d7cc8ff0ca 100644 --- a/tests/src/java/org/apache/log4j/MyPatternLayout.java +++ b/tests/src/java/org/apache/log4j/MyPatternLayout.java @@ -50,4 +50,13 @@ PatternParser createPatternParser(String pattern) { return new MyPatternParser( pattern == null ? DEFAULT_CONVERSION_PATTERN : pattern); } + + public + static void main(String[] args) { + Layout layout = new MyPatternLayout("[counter=%.10#] - %m%n"); + 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/tests/src/java/org/apache/log4j/MyPatternParser.java b/tests/src/java/org/apache/log4j/MyPatternParser.java index 98eeb36e34..25379fca38 100644 --- a/tests/src/java/org/apache/log4j/MyPatternParser.java +++ b/tests/src/java/org/apache/log4j/MyPatternParser.java @@ -34,7 +34,7 @@ See source code for more details. - @see org.apache.log4j.MyPatternLayout + @see org.apache.log4j.examples.MyPatternLayout @see org.apache.log4j.helpers.PatternParser @see org.apache.log4j.PatternLayout diff --git a/tests/src/java/org/apache/log4j/NDCTestCase.java b/tests/src/java/org/apache/log4j/NDCTestCase.java deleted file mode 100644 index 3e35b55455..0000000000 --- a/tests/src/java/org/apache/log4j/NDCTestCase.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.apache.log4j.util.*; - - -/** - Test the configuration of the hierarchy-wide threshold. - - @author Ceki Gülcü -*/ -public class NDCTestCase extends TestCase { - static String TEMP = "output/temp"; - static Logger logger = Logger.getLogger(NDCTestCase.class); - - public NDCTestCase(String name) { - super(name); - } - - public void setUp() { - } - - public void tearDown() { - System.out.println("Tearing down test case."); - logger.getLoggerRepository().resetConfiguration(); - } - - public void test1() throws Exception { - PropertyConfigurator.configure("input/ndc/NDC1.properties"); - common(); - assertTrue(Compare.compare(TEMP, "witness/ndc/NDC.1")); - } - - static void common() { - commonLog(); - NDC.push("n1"); - commonLog(); - NDC.push("n2"); - NDC.push("n3"); - commonLog(); - NDC.pop(); - commonLog(); - NDC.clear(); - commonLog(); - } - - static void commonLog() { - logger.debug("m1"); - logger.info("m2"); - logger.warn("m3"); - logger.error("m4"); - logger.fatal("m5"); - } - - public static Test suite() { - TestSuite suite = new TestSuite(); - suite.addTest(new NDCTestCase("test1")); - return suite; - } -} diff --git a/tests/src/java/org/apache/log4j/PatternLayoutTest.java b/tests/src/java/org/apache/log4j/PatternLayoutTest.java index 07f1ad5c2c..0421d2ec53 100644 --- a/tests/src/java/org/apache/log4j/PatternLayoutTest.java +++ b/tests/src/java/org/apache/log4j/PatternLayoutTest.java @@ -116,7 +116,7 @@ public void testFormatResize() { /** * Class to ensure that protected members are still available. */ - private static final class DerivedPatternLayout extends PatternLayout { + public static final class DerivedPatternLayout extends PatternLayout { /** * Constructs a new instance of DerivedPatternLayout. */ @@ -126,7 +126,6 @@ public DerivedPatternLayout() { /** * Get BUF_SIZE. * @return return initial buffer size in characters. - * @deprecated */ public int getBufSize() { return BUF_SIZE; @@ -135,7 +134,6 @@ public int getBufSize() { /** * Get MAX_CAPACITY. * @return maximum capacity in characters. - * @deprecated */ public int getMaxCapacity() { return MAX_CAPACITY; diff --git a/tests/src/java/org/apache/log4j/PatternLayoutTestCase.java b/tests/src/java/org/apache/log4j/PatternLayoutTestCase.java index e7b1a14a54..9578523097 100644 --- a/tests/src/java/org/apache/log4j/PatternLayoutTestCase.java +++ b/tests/src/java/org/apache/log4j/PatternLayoutTestCase.java @@ -30,64 +30,57 @@ import org.apache.log4j.util.SunReflectFilter; import org.apache.log4j.util.Transformer; -import java.io.FileReader; -import java.text.ParsePosition; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.TimeZone; - - public class PatternLayoutTestCase extends TestCase { + static String TEMP = "output/temp"; static String FILTERED = "output/filtered"; + + Logger root; + Logger logger; + static String EXCEPTION1 = "java.lang.Exception: Just testing"; - static String EXCEPTION2 = "\\s*at .*\\(.*:\\d{1,4}\\)"; + static String EXCEPTION2 = "\\s*at .*\\(.*\\)"; static String EXCEPTION3 = "\\s*at .*\\(Native Method\\)"; static String EXCEPTION4 = "\\s*at .*\\(.*Compiled Code\\)"; + static String EXCEPTION5 = "\\s*at .*\\(.*libgcj.*\\)"; - static String PAT0 = - "\\[main]\\ (DEBUG|INFO|WARN|ERROR|FATAL) .* - Message \\d{1,2}"; + static String PAT0 = "\\[main]\\ (TRACE|DEBUG|INFO |WARN |ERROR|FATAL) .* - Message \\d{1,2}"; static String PAT1 = Filter.ISO8601_PAT + " " + PAT0; - static String PAT2 = Filter.ABSOLUTE_DATE_AND_TIME_PAT + " " + PAT0; - static String PAT3 = Filter.ABSOLUTE_TIME_PAT + " " + PAT0; - static String PAT4 = Filter.RELATIVE_TIME_PAT + " " + PAT0; - static String PAT5 = - "\\[main]\\ (DEBUG|INFO|WARN|ERROR|FATAL) .* : Message \\d{1,2}"; - static String PAT6 = - "\\[main]\\ (DEBUG|INFO |WARN |ERROR|FATAL) org.apache.log4j.PatternLayoutTestCase.common\\(PatternLayoutTestCase.java:\\d{1,4}\\): Message \\d{1,2}"; - static String PAT11a = - "^(DEBUG|INFO |WARN |ERROR|FATAL) \\[main]\\ log4j.PatternLayoutTest: Message \\d{1,2}"; - static String PAT11b = - "^(DEBUG|INFO |WARN |ERROR|FATAL) \\[main]\\ root: Message \\d{1,2}"; - static String PAT12 = - "^\\[main]\\ (DEBUG|INFO |WARN |ERROR|FATAL) " - + "org.apache.log4j.PatternLayoutTestCase.common\\(PatternLayoutTestCase.java:\\d{3}\\): " - + "Message \\d{1,2}"; - static String PAT13 = - "^\\[main]\\ (DEBUG|INFO |WARN |ERROR|FATAL) " - + "apache.log4j.PatternLayoutTestCase.common\\(PatternLayoutTestCase.java:\\d{3}\\): " - + "Message \\d{1,2}"; - static String PAT14 = - "^(TRACE|DEBUG| INFO| WARN|ERROR|FATAL)\\ \\d{1,2}\\ *- Message \\d{1,2}"; - static String PAT_MDC_1 = ""; - Logger root; - Logger logger; + static String PAT2 = Filter.ABSOLUTE_DATE_AND_TIME_PAT+ " " + PAT0; + static String PAT3 = Filter.ABSOLUTE_TIME_PAT+ " " + PAT0; + static String PAT4 = Filter.RELATIVE_TIME_PAT+ " " + PAT0; + + static String PAT5 = "\\[main]\\ (TRACE|DEBUG|INFO |WARN |ERROR|FATAL) .* : Message \\d{1,2}"; + static String PAT6 = "\\[main]\\ (TRACE|DEBUG|INFO |WARN |ERROR|FATAL) org.apache.log4j.PatternLayoutTestCase.common\\(PatternLayoutTestCase.java(:\\d{1,4})?\\): Message \\d{1,2}"; + + static String PAT11a = "^(TRACE|DEBUG|INFO |WARN |ERROR|FATAL) \\[main]\\ log4j.PatternLayoutTestCase: Message \\d{1,2}"; + static String PAT11b = "^(TRACE|DEBUG|INFO |WARN |ERROR|FATAL) \\[main]\\ root: Message \\d{1,2}"; + + static String PAT12 = "^\\[main]\\ (TRACE|DEBUG|INFO |WARN |ERROR|FATAL) "+ + "org.apache.log4j.PatternLayoutTestCase.common\\(PatternLayoutTestCase.java:\\d{3}\\): "+ + "Message \\d{1,2}"; + + static String PAT13 = "^\\[main]\\ (TRACE|DEBUG|INFO |WARN |ERROR|FATAL) "+ + "apache.log4j.PatternLayoutTestCase.common\\(PatternLayoutTestCase.java:\\d{3}\\): "+ + "Message \\d{1,2}"; - public PatternLayoutTestCase(final String name) { + static String PAT14 = "^(TRACE|DEBUG| INFO| WARN|ERROR|FATAL)\\ \\d{1,2}\\ *- Message \\d{1,2}"; + + public PatternLayoutTestCase(String name) { super(name); } public void setUp() { root = Logger.getRootLogger(); - logger = Logger.getLogger(PatternLayoutTest.class); + logger = Logger.getLogger(PatternLayoutTestCase.class); } - public void tearDown() { + public void tearDown() { root.getLoggerRepository().resetConfiguration(); } public void test1() throws Exception { - PropertyConfigurator.configure("input/pattern/patternLayout1.properties"); + PropertyConfigurator.configure("input/patternLayout1.properties"); common(); Transformer.transform( TEMP, FILTERED, @@ -95,294 +88,235 @@ public void test1() throws Exception { new LineNumberFilter(), new SunReflectFilter(), new JunitTestRunnerFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.1")); + assertTrue(Compare.compare(FILTERED, "witness/patternLayout.1")); } public void test2() throws Exception { - PropertyConfigurator.configure("input/pattern/patternLayout2.properties"); + PropertyConfigurator.configure("input/patternLayout2.properties"); common(); - - ControlFilter cf1 = - new ControlFilter( - new String[] { PAT1, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + ControlFilter cf1 = new ControlFilter(new String[]{PAT1, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); Transformer.transform( TEMP, FILTERED, new Filter[] { cf1, new LineNumberFilter(), new ISO8601Filter(), new SunReflectFilter(), new JunitTestRunnerFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.2")); + assertTrue(Compare.compare(FILTERED, "witness/patternLayout.2")); } public void test3() throws Exception { - PropertyConfigurator.configure("input/pattern/patternLayout3.properties"); + PropertyConfigurator.configure("input/patternLayout3.properties"); common(); - - ControlFilter cf1 = - new ControlFilter( - new String[] { PAT1, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + ControlFilter cf1 = new ControlFilter(new String[]{PAT1, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); Transformer.transform( TEMP, FILTERED, new Filter[] { cf1, new LineNumberFilter(), new ISO8601Filter(), new SunReflectFilter(), new JunitTestRunnerFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.3")); + assertTrue(Compare.compare(FILTERED, "witness/patternLayout.3")); } // Output format: - // 06 avr. 2002 18:30:58,937 [main] DEBUG atternLayoutTest - Message 0 + // 06 avr. 2002 18:30:58,937 [main] DEBUG rnLayoutTestCase - Message 0 public void test4() throws Exception { - PropertyConfigurator.configure("input/pattern/patternLayout4.properties"); + PropertyConfigurator.configure("input/patternLayout4.properties"); common(); - - ControlFilter cf1 = - new ControlFilter( - new String[] { PAT2, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + ControlFilter cf1 = new ControlFilter(new String[]{PAT2, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); Transformer.transform( TEMP, FILTERED, new Filter[] { cf1, new LineNumberFilter(), new AbsoluteDateAndTimeFilter(), new SunReflectFilter(), new JunitTestRunnerFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.4")); + assertTrue(Compare.compare(FILTERED, "witness/patternLayout.4")); } public void test5() throws Exception { - PropertyConfigurator.configure("input/pattern/patternLayout5.properties"); + PropertyConfigurator.configure("input/patternLayout5.properties"); common(); - - ControlFilter cf1 = - new ControlFilter( - new String[] { PAT2, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + ControlFilter cf1 = new ControlFilter(new String[]{PAT2, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); Transformer.transform( TEMP, FILTERED, new Filter[] { cf1, new LineNumberFilter(), new AbsoluteDateAndTimeFilter(), new SunReflectFilter(), new JunitTestRunnerFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.5")); + assertTrue(Compare.compare(FILTERED, "witness/patternLayout.5")); } - // 18:54:19,201 [main] DEBUG atternLayoutTest - Message 0 + // 18:54:19,201 [main] DEBUG rnLayoutTestCase - Message 0 public void test6() throws Exception { - PropertyConfigurator.configure("input/pattern/patternLayout6.properties"); + PropertyConfigurator.configure("input/patternLayout6.properties"); common(); - - ControlFilter cf1 = - new ControlFilter( - new String[] { PAT3, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + ControlFilter cf1 = new ControlFilter(new String[]{PAT3, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); Transformer.transform( TEMP, FILTERED, new Filter[] { cf1, new LineNumberFilter(), new AbsoluteTimeFilter(), new SunReflectFilter(), new JunitTestRunnerFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.6")); + assertTrue(Compare.compare(FILTERED, "witness/patternLayout.6")); } + public void test7() throws Exception { - PropertyConfigurator.configure("input/pattern/patternLayout7.properties"); + PropertyConfigurator.configure("input/patternLayout7.properties"); common(); - - ControlFilter cf1 = - new ControlFilter( - new String[] { PAT3, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + ControlFilter cf1 = new ControlFilter(new String[]{PAT3, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); Transformer.transform( TEMP, FILTERED, new Filter[] { cf1, new LineNumberFilter(), new AbsoluteTimeFilter(), new SunReflectFilter(), new JunitTestRunnerFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.7")); + assertTrue(Compare.compare(FILTERED, "witness/patternLayout.7")); } public void test8() throws Exception { - PropertyConfigurator.configure("input/pattern/patternLayout8.properties"); + PropertyConfigurator.configure("input/patternLayout8.properties"); common(); - - ControlFilter cf1 = - new ControlFilter( - new String[] { PAT4, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + ControlFilter cf1 = new ControlFilter(new String[]{PAT4, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); Transformer.transform( TEMP, FILTERED, new Filter[] { cf1, new LineNumberFilter(), new RelativeTimeFilter(), new SunReflectFilter(), new JunitTestRunnerFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.8")); + assertTrue(Compare.compare(FILTERED, "witness/patternLayout.8")); } public void test9() throws Exception { - PropertyConfigurator.configure("input/pattern/patternLayout9.properties"); + PropertyConfigurator.configure("input/patternLayout9.properties"); common(); - - ControlFilter cf1 = - new ControlFilter( - new String[] { PAT5, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + ControlFilter cf1 = new ControlFilter(new String[]{PAT5, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); Transformer.transform( TEMP, FILTERED, new Filter[] { cf1, new LineNumberFilter(), new SunReflectFilter(), new JunitTestRunnerFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.9")); + assertTrue(Compare.compare(FILTERED, "witness/patternLayout.9")); } public void test10() throws Exception { - PropertyConfigurator.configure("input/pattern/patternLayout10.properties"); + PropertyConfigurator.configure("input/patternLayout10.properties"); common(); - - ControlFilter cf1 = - new ControlFilter( - new String[] { PAT6, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + ControlFilter cf1 = new ControlFilter(new String[]{PAT6, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); Transformer.transform( TEMP, FILTERED, new Filter[] { cf1, new LineNumberFilter(), new SunReflectFilter(), new JunitTestRunnerFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.10")); + assertTrue(Compare.compare(FILTERED, "witness/patternLayout.10")); } public void test11() throws Exception { - PropertyConfigurator.configure("input/pattern/patternLayout11.properties"); + PropertyConfigurator.configure("input/patternLayout11.properties"); common(); - - ControlFilter cf1 = - new ControlFilter( - new String[] { PAT11a, PAT11b, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + ControlFilter cf1 = new ControlFilter(new String[]{PAT11a, PAT11b, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); Transformer.transform( TEMP, FILTERED, new Filter[] { cf1, new LineNumberFilter(), new SunReflectFilter(), new JunitTestRunnerFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.11")); + assertTrue(Compare.compare(FILTERED, "witness/patternLayout.11")); } public void test12() throws Exception { - PropertyConfigurator.configure("input/pattern/patternLayout12.properties"); + PropertyConfigurator.configure("input/patternLayout12.properties"); common(); - - ControlFilter cf1 = - new ControlFilter( - new String[] { PAT12, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + ControlFilter cf1 = new ControlFilter(new String[]{PAT12, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); Transformer.transform( TEMP, FILTERED, new Filter[] { cf1, new LineNumberFilter(), new SunReflectFilter(), new JunitTestRunnerFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.12")); + assertTrue(Compare.compare(FILTERED, "witness/patternLayout.12")); } public void test13() throws Exception { - PropertyConfigurator.configure("input/pattern/patternLayout13.properties"); + PropertyConfigurator.configure("input/patternLayout13.properties"); common(); - - ControlFilter cf1 = - new ControlFilter( - new String[] { PAT13, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); + ControlFilter cf1 = new ControlFilter(new String[]{PAT13, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); Transformer.transform( TEMP, FILTERED, new Filter[] { cf1, new LineNumberFilter(), new SunReflectFilter(), new JunitTestRunnerFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.13")); + assertTrue(Compare.compare(FILTERED, "witness/patternLayout.13")); } - /** - * Test of class abbreviation. - * - * @throws Exception - */ - public void test14() throws Exception { - PropertyConfigurator.configure("input/pattern/patternLayout14.properties"); - common(); - - Transformer.transform( - TEMP, FILTERED, - new Filter[] { - new LineNumberFilter(), new SunReflectFilter(), - new JunitTestRunnerFilter() - }); - assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.14")); - } - - - public void testMDC1() throws Exception { - PropertyConfigurator.configure("input/pattern/patternLayout.mdc.1.properties"); - MDC.put("key1", "va11"); - MDC.put("key2", "va12"); - logger.debug("Hello World"); - MDC.clear(); - + public void test14() throws Exception { + PropertyConfigurator.configure("input/patternLayout14.properties"); + common(); + ControlFilter cf1 = new ControlFilter(new String[]{PAT14, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); Transformer.transform( TEMP, FILTERED, new Filter[] { - new LineNumberFilter(), new SunReflectFilter(), + cf1, new LineNumberFilter(), new SunReflectFilter(), new JunitTestRunnerFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.mdc.1")); + assertTrue(Compare.compare(FILTERED, "witness/patternLayout.14")); } - /** - * Tests log4j 1.2 style extension of PatternLayout. - * Was test14 in log4j 1.2. - * @throws Exception - */ - public void test15() throws Exception { - PropertyConfigurator.configure("input/pattern/patternLayout15.properties"); - common(); - ControlFilter cf1 = new ControlFilter(new String[]{PAT14, EXCEPTION1, - EXCEPTION2, EXCEPTION3, EXCEPTION4}); - Transformer.transform( - TEMP, FILTERED, - new Filter[] { - cf1, new LineNumberFilter(), new SunReflectFilter(), - new JunitTestRunnerFilter() - }); - assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.15")); + public void testMDC1() throws Exception { + PropertyConfigurator.configure("input/patternLayout.mdc.1.properties"); + MDC.put("key1", "va11"); + MDC.put("key2", "va12"); + logger.debug("Hello World"); + MDC.remove("key1"); + MDC.remove("key2"); + + assertTrue(Compare.compare(TEMP, "witness/patternLayout.mdc.1")); } - /** - * Tests explicit UTC time zone in pattern. - * @throws Exception - */ - public void test16() throws Exception { - final long start = new Date().getTime(); - PropertyConfigurator.configure("input/pattern/patternLayout16.properties"); - common(); - final long end = new Date().getTime(); - FileReader reader = new FileReader("output/patternLayout16.log"); - char chars[] = new char[50]; - reader.read(chars, 0, chars.length); - reader.close(); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - format.setTimeZone(TimeZone.getTimeZone("GMT+0")); - String utcStr = new String(chars, 0, 19); - Date utcDate = format.parse(utcStr, new ParsePosition(0)); - assertTrue(utcDate.getTime() >= start - 1000 && utcDate.getTime() < end + 1000); - String cstStr = new String(chars, 21, 19); - format.setTimeZone(TimeZone.getTimeZone("GMT-6")); - Date cstDate = format.parse(cstStr, new ParsePosition(0)); - assertFalse(cstStr.equals(utcStr)); - assertTrue(cstDate.getTime() >= start - 1000 && cstDate.getTime() < end + 1000); + public void testMDCClear() throws Exception { + PropertyConfigurator.configure("input/patternLayout.mdc.1.properties"); + MDC.put("key1", "va11"); + MDC.put("key2", "va12"); + logger.debug("Hello World"); + MDC.clear(); + logger.debug("Hello World"); + + assertTrue(Compare.compare(TEMP, "witness/patternLayout.mdc.clear")); } + void common() { + String oldThreadName = Thread.currentThread().getName(); + Thread.currentThread().setName("main"); + int i = -1; + logger.trace("Message " + ++i); + root.trace("Message " + i); + logger.debug("Message " + ++i); root.debug("Message " + i); - logger.info("Message " + ++i); + logger.info ("Message " + ++i); root.info("Message " + i); - logger.warn("Message " + ++i); + logger.warn ("Message " + ++i); root.warn("Message " + i); logger.error("Message " + ++i); @@ -392,87 +326,15 @@ void common() { root.log(Level.FATAL, "Message " + i); Exception e = new Exception("Just testing"); - + logger.trace("Message " + ++i, e); logger.debug("Message " + ++i, e); logger.info("Message " + ++i, e); - logger.warn("Message " + ++i, e); + logger.warn("Message " + ++i , e); logger.error("Message " + ++i, e); logger.log(Level.FATAL, "Message " + ++i, e); - } - /** - Test case for MDC conversion pattern. */ - public void testMDC2() throws Exception { - String OUTPUT_FILE = "output/patternLayout.mdc.2"; - String WITNESS_FILE = "witness/pattern/patternLayout.mdc.2"; - - String mdcMsgPattern1 = "%m : %X%n"; - String mdcMsgPattern2 = "%m : %X{key1}%n"; - String mdcMsgPattern3 = "%m : %X{key2}%n"; - String mdcMsgPattern4 = "%m : %X{key3}%n"; - String mdcMsgPattern5 = "%m : %X{key1},%X{key2},%X{key3}%n"; - - // set up appender - PatternLayout layout = new PatternLayout("%m%n"); - Appender appender = new FileAppender(layout, OUTPUT_FILE, false); - - // set appender on root and set level to debug - root.addAppender(appender); - root.setLevel(Level.DEBUG); - - // output starting message - root.debug("starting mdc pattern test"); - - layout.setConversionPattern(mdcMsgPattern1); - layout.activateOptions(); - root.debug("empty mdc, no key specified in pattern"); - - layout.setConversionPattern(mdcMsgPattern2); - layout.activateOptions(); - root.debug("empty mdc, key1 in pattern"); - - layout.setConversionPattern(mdcMsgPattern3); - layout.activateOptions(); - root.debug("empty mdc, key2 in pattern"); - - layout.setConversionPattern(mdcMsgPattern4); - layout.activateOptions(); - root.debug("empty mdc, key3 in pattern"); - - layout.setConversionPattern(mdcMsgPattern5); - layout.activateOptions(); - root.debug("empty mdc, key1, key2, and key3 in pattern"); - - MDC.put("key1", "value1"); - MDC.put("key2", "value2"); - - layout.setConversionPattern(mdcMsgPattern1); - layout.activateOptions(); - root.debug("filled mdc, no key specified in pattern"); - - layout.setConversionPattern(mdcMsgPattern2); - layout.activateOptions(); - root.debug("filled mdc, key1 in pattern"); - - layout.setConversionPattern(mdcMsgPattern3); - layout.activateOptions(); - root.debug("filled mdc, key2 in pattern"); - - layout.setConversionPattern(mdcMsgPattern4); - layout.activateOptions(); - root.debug("filled mdc, key3 in pattern"); - - layout.setConversionPattern(mdcMsgPattern5); - layout.activateOptions(); - root.debug("filled mdc, key1, key2, and key3 in pattern"); - - MDC.remove("key1"); - MDC.remove("key2"); - - layout.setConversionPattern("%m%n"); - layout.activateOptions(); - root.debug("finished mdc pattern test"); - - assertTrue(Compare.compare(OUTPUT_FILE, WITNESS_FILE)); + Thread.currentThread().setName(oldThreadName); } + + } diff --git a/tests/src/java/org/apache/log4j/PriorityTest.java b/tests/src/java/org/apache/log4j/PriorityTest.java index 47453faa78..68c748202a 100644 --- a/tests/src/java/org/apache/log4j/PriorityTest.java +++ b/tests/src/java/org/apache/log4j/PriorityTest.java @@ -19,6 +19,8 @@ import junit.framework.TestCase; +import java.util.Locale; + /** * Tests of Priority. @@ -183,4 +185,28 @@ public void testToPriorityStringPriority() { public void testToPriorityIntPriority() { assertTrue(Priority.toPriority(17, Priority.DEBUG) == Priority.DEBUG); } + + /** + * Test that dotless lower I + "nfo" is recognized as INFO. + * @deprecated + */ + public void testDotlessLowerI() { + Priority level = Priority.toPriority("\u0131nfo"); + assertEquals("INFO", level.toString()); + } + + /** + * Test that dotted lower I + "nfo" is recognized as INFO + * even in Turkish locale. + * @deprecated + */ + public void testDottedLowerI() { + Locale defaultLocale = Locale.getDefault(); + Locale turkey = new Locale("tr", "TR"); + Locale.setDefault(turkey); + Priority level = Priority.toPriority("info"); + Locale.setDefault(defaultLocale); + assertEquals("INFO", level.toString()); + } + } diff --git a/tests/src/java/org/apache/log4j/PropertyConfiguratorTest.java b/tests/src/java/org/apache/log4j/PropertyConfiguratorTest.java index 23c4b573e8..4b5e030197 100644 --- a/tests/src/java/org/apache/log4j/PropertyConfiguratorTest.java +++ b/tests/src/java/org/apache/log4j/PropertyConfiguratorTest.java @@ -15,10 +15,25 @@ * limitations under the License. */ package org.apache.log4j; -import java.io.*; -import junit.framework.*; -import org.apache.log4j.PropertyConfigurator; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; import java.net.URL; +import java.util.Properties; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import junit.framework.TestCase; + +import org.apache.log4j.spi.Filter; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.spi.OptionHandler; +import org.apache.log4j.spi.ThrowableRenderer; +import org.apache.log4j.spi.ThrowableRendererSupport; +import org.apache.log4j.varia.LevelRangeFilter; /** * Test property configurator. @@ -30,7 +45,7 @@ public PropertyConfiguratorTest(final String testName) { } /** - * Test for bug 19108. + * Test for bug 40944. * Did not catch IllegalArgumentException on Properties.load * and close input stream. * @throws IOException if IOException creating properties file. @@ -47,7 +62,7 @@ public void testBadUnicodeEscape() throws IOException { } /** - * Test for bug 19108. + * Test for bug 40944. * configure(URL) never closed opened stream. * @throws IOException if IOException creating properties file. */ @@ -63,7 +78,7 @@ public void testURL() throws IOException { } /** - * Test for bug 19108. + * Test for bug 40944. * configure(URL) did not catch IllegalArgumentException and * did not close stream. * @throws IOException if IOException creating properties file. @@ -79,4 +94,276 @@ public void testURLBadEscape() throws IOException { assertFalse(file.exists()); } + /** + * Tests configuring Log4J from an InputStream. + * + * @since 1.2.17 + */ + public void testInputStream() throws IOException { + File file = new File("input/filter1.properties"); + assertTrue(file.exists()); + FileInputStream inputStream = new FileInputStream(file); + try { + PropertyConfigurator.configure(inputStream); + } finally { + inputStream.close(); + } + this.validateNested(); + LogManager.resetConfiguration(); + } + + public void validateNested() { + RollingFileAppender rfa = (RollingFileAppender) + Logger.getLogger("org.apache.log4j.PropertyConfiguratorTest") + .getAppender("ROLLING"); + FixedWindowRollingPolicy rollingPolicy = (FixedWindowRollingPolicy) rfa.getRollingPolicy(); + assertEquals("filterBase-test1.log", rollingPolicy.getActiveFileName()); + assertEquals("filterBased-test1.%i", rollingPolicy.getFileNamePattern()); + assertEquals(0, rollingPolicy.getMinIndex()); + assertTrue(rollingPolicy.isActivated()); + FilterBasedTriggeringPolicy triggeringPolicy = + (FilterBasedTriggeringPolicy) rfa.getTriggeringPolicy(); + LevelRangeFilter filter = (LevelRangeFilter) triggeringPolicy.getFilter(); + assertTrue(Level.INFO.equals(filter.getLevelMin())); + } + + /** + * Test for bug 47465. + * configure(URL) did not close opened JarURLConnection. + * @throws IOException if IOException creating properties jar. + */ + public void testJarURL() throws IOException { + File dir = new File("output"); + dir.mkdirs(); + File file = new File("output/properties.jar"); + ZipOutputStream zos = + new ZipOutputStream(new FileOutputStream(file)); + zos.putNextEntry(new ZipEntry(LogManager.DEFAULT_CONFIGURATION_FILE)); + zos.write("log4j.rootLogger=debug".getBytes()); + zos.closeEntry(); + zos.close(); + URL url = new URL("jar:" + file.toURL() + "!/" + + LogManager.DEFAULT_CONFIGURATION_FILE); + PropertyConfigurator.configure(url); + assertTrue(file.delete()); + assertFalse(file.exists()); + } + + /** + * Test processing of log4j.reset property, see bug 17531. + * + */ + public void testReset() { + VectorAppender appender = new VectorAppender(); + appender.setName("A1"); + Logger.getRootLogger().addAppender(appender); + Properties props = new Properties(); + props.put("log4j.reset", "true"); + PropertyConfigurator.configure(props); + assertNull(Logger.getRootLogger().getAppender("A1")); + LogManager.resetConfiguration(); + } + + + /** + * Mock definition of org.apache.log4j.rolling.RollingPolicy + * from extras companion. + */ + public static class RollingPolicy implements OptionHandler { + private boolean activated = false; + + public RollingPolicy() { + + } + public void activateOptions() { + activated = true; + } + + public final boolean isActivated() { + return activated; + } + + } + + /** + * Mock definition of FixedWindowRollingPolicy from extras companion. + */ + public static final class FixedWindowRollingPolicy extends RollingPolicy { + private String activeFileName; + private String fileNamePattern; + private int minIndex; + + public FixedWindowRollingPolicy() { + minIndex = -1; + } + + public String getActiveFileName() { + return activeFileName; + } + public void setActiveFileName(final String val) { + activeFileName = val; + } + + public String getFileNamePattern() { + return fileNamePattern; + } + public void setFileNamePattern(final String val) { + fileNamePattern = val; + } + + public int getMinIndex() { + return minIndex; + } + + public void setMinIndex(final int val) { + minIndex = val; + } + } + + /** + * Mock definition of TriggeringPolicy from extras companion. + */ + public static class TriggeringPolicy implements OptionHandler { + private boolean activated = false; + + public TriggeringPolicy() { + + } + public void activateOptions() { + activated = true; + } + + public final boolean isActivated() { + return activated; + } + + } + + /** + * Mock definition of FilterBasedTriggeringPolicy from extras companion. + */ + public static final class FilterBasedTriggeringPolicy extends TriggeringPolicy { + private Filter filter; + public FilterBasedTriggeringPolicy() { + } + + public void setFilter(final Filter val) { + filter = val; + } + + public Filter getFilter() { + return filter; + + } + } + + /** + * Mock definition of org.apache.log4j.rolling.RollingFileAppender + * from extras companion. + */ + public static final class RollingFileAppender extends AppenderSkeleton { + private RollingPolicy rollingPolicy; + private TriggeringPolicy triggeringPolicy; + private boolean append; + + public RollingFileAppender() { + + } + + public RollingPolicy getRollingPolicy() { + return rollingPolicy; + } + + public void setRollingPolicy(final RollingPolicy policy) { + rollingPolicy = policy; + } + + public TriggeringPolicy getTriggeringPolicy() { + return triggeringPolicy; + } + + public void setTriggeringPolicy(final TriggeringPolicy policy) { + triggeringPolicy = policy; + } + + public boolean getAppend() { + return append; + } + + public void setAppend(boolean val) { + append = val; + } + + public void close() { + + } + + public boolean requiresLayout() { + return true; + } + + public void append(final LoggingEvent event) { + + } + } + + /** + * Tests processing of nested objects, see bug 36384. + */ + public void testNested() { + try { + PropertyConfigurator.configure("input/filter1.properties"); + this.validateNested(); + } finally { + LogManager.resetConfiguration(); + } + } + + + /** + * Mock ThrowableRenderer for testThrowableRenderer. See bug 45721. + */ + public static class MockThrowableRenderer implements ThrowableRenderer, OptionHandler { + private boolean activated = false; + private boolean showVersion = true; + + public MockThrowableRenderer() { + } + + public void activateOptions() { + activated = true; + } + + public boolean isActivated() { + return activated; + } + + public String[] doRender(final Throwable t) { + return new String[0]; + } + + public void setShowVersion(boolean v) { + showVersion = v; + } + + public boolean getShowVersion() { + return showVersion; + } + } + + /** + * Test of log4j.throwableRenderer support. See bug 45721. + */ + public void testThrowableRenderer() { + Properties props = new Properties(); + props.put("log4j.throwableRenderer", "org.apache.log4j.PropertyConfiguratorTest$MockThrowableRenderer"); + props.put("log4j.throwableRenderer.showVersion", "false"); + PropertyConfigurator.configure(props); + ThrowableRendererSupport repo = (ThrowableRendererSupport) LogManager.getLoggerRepository(); + MockThrowableRenderer renderer = (MockThrowableRenderer) repo.getThrowableRenderer(); + LogManager.resetConfiguration(); + assertNotNull(renderer); + assertEquals(true, renderer.isActivated()); + assertEquals(false, renderer.getShowVersion()); + } } diff --git a/tests/src/java/org/apache/log4j/RFATestCase.java b/tests/src/java/org/apache/log4j/RFATestCase.java index c2ff55bc62..0d11fc200d 100644 --- a/tests/src/java/org/apache/log4j/RFATestCase.java +++ b/tests/src/java/org/apache/log4j/RFATestCase.java @@ -20,6 +20,7 @@ import junit.framework.TestCase; import java.io.File; +import java.io.FileWriter; import java.io.IOException; /** @@ -113,4 +114,124 @@ public void test3ParamConstructor() throws IOException { assertEquals(1, appender.getMaxBackupIndex()); } + /** + * Test locking of .1 file. + */ + public void testLockDotOne() throws Exception { + Logger logger = Logger.getLogger(RFATestCase.class); + Logger root = Logger.getRootLogger(); + PatternLayout layout = new PatternLayout("%m\n"); + org.apache.log4j.RollingFileAppender rfa = + new org.apache.log4j.RollingFileAppender(); + rfa.setName("ROLLING"); + rfa.setLayout(layout); + rfa.setAppend(false); + rfa.setMaxBackupIndex(10); + rfa.setMaximumFileSize(100); + rfa.setFile("output/RFA-dot1.log"); + rfa.activateOptions(); + root.addAppender(rfa); + + new File("output/RFA-dot1.log.2").delete(); + + FileWriter dot1 = new FileWriter("output/RFA-dot1.log.1"); + dot1.write("Locked file"); + FileWriter dot5 = new FileWriter("output/RFA-dot1.log.5"); + dot5.write("Unlocked file"); + dot5.close(); + + // Write exactly 10 bytes with each log + for (int i = 0; i < 15; i++) { + if (i < 10) { + logger.debug("Hello---" + i); + } else if (i < 100) { + logger.debug("Hello--" + i); + } + } + dot1.close(); + + for (int i = 15; i < 25; i++) { + logger.debug("Hello--" + i); + } + rfa.close(); + + + assertTrue(new File("output/RFA-dot1.log.7").exists()); + // + // if .2 is the locked file then + // renaming wasn't successful until the file was closed + if (new File("output/RFA-dot1.log.2").length() < 15) { + assertEquals(50, new File("output/RFA-dot1.log").length()); + assertEquals(200, new File("output/RFA-dot1.log.1").length()); + } else { + assertTrue(new File("output/RFA-dot1.log").exists()); + assertTrue(new File("output/RFA-dot1.log.1").exists()); + assertTrue(new File("output/RFA-dot1.log.2").exists()); + assertTrue(new File("output/RFA-dot1.log.3").exists()); + assertFalse(new File("output/RFA-dot1.log.4").exists()); + } + } + + + /** + * Test locking of .3 file. + */ + public void testLockDotThree() throws Exception { + Logger logger = Logger.getLogger(RFATestCase.class); + Logger root = Logger.getRootLogger(); + PatternLayout layout = new PatternLayout("%m\n"); + org.apache.log4j.RollingFileAppender rfa = + new org.apache.log4j.RollingFileAppender(); + rfa.setName("ROLLING"); + rfa.setLayout(layout); + rfa.setAppend(false); + rfa.setMaxBackupIndex(10); + rfa.setMaximumFileSize(100); + rfa.setFile("output/RFA-dot3.log"); + rfa.activateOptions(); + root.addAppender(rfa); + + new File("output/RFA-dot3.log.1").delete(); + new File("output/RFA-dot3.log.2").delete(); + new File("output/RFA-dot3.log.4").delete(); + + FileWriter dot3 = new FileWriter("output/RFA-dot3.log.3"); + dot3.write("Locked file"); + FileWriter dot5 = new FileWriter("output/RFA-dot3.log.5"); + dot5.write("Unlocked file"); + dot5.close(); + + // Write exactly 10 bytes with each log + for (int i = 0; i < 15; i++) { + if (i < 10) { + logger.debug("Hello---" + i); + } else if (i < 100) { + logger.debug("Hello--" + i); + } + } + dot3.close(); + + for (int i = 15; i < 35; i++) { + logger.debug("Hello--" + i); + } + rfa.close(); + + assertTrue(new File("output/RFA-dot3.log.8").exists()); + // + // if .3 is the locked file then + // renaming wasn't successful until file was closed + if (new File("output/RFA-dot3.log.5").exists()) { + assertEquals(50, new File("output/RFA-dot3.log").length()); + assertEquals(100, new File("output/RFA-dot3.log.1").length()); + assertEquals(200, new File("output/RFA-dot3.log.2").length()); + } else { + assertTrue(new File("output/RFA-dot3.log").exists()); + assertTrue(new File("output/RFA-dot3.log.1").exists()); + assertTrue(new File("output/RFA-dot3.log.2").exists()); + assertTrue(new File("output/RFA-dot3.log.3").exists()); + assertFalse(new File("output/RFA-dot3.log.4").exists()); + } + } + + } diff --git a/tests/src/java/org/apache/log4j/SimpleLog.java b/tests/src/java/org/apache/log4j/SimpleLog.java deleted file mode 100644 index 79c0d0ad9d..0000000000 --- a/tests/src/java/org/apache/log4j/SimpleLog.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j; - -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.config.ConfiguratorBase; -import org.apache.log4j.joran.JoranConfigurator; -import org.apache.log4j.spi.LoggerRepository; - - -/** - * Simple application used for manual testing. - * - * @author Ceki Gülcü - */ -public class SimpleLog { - - public static void main(String[] args) throws Exception { - if (args.length != 1) { - usage("Wrong number of arguments."); - } - - String configFile = args[0]; - LoggerRepository repo = LogManager.getLoggerRepository(); - ConfiguratorBase configurator; - if (configFile.endsWith(".xml")) { - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure(configFile, repo); - jc.dumpErrors(); - } else { - PropertyConfigurator pc = new PropertyConfigurator(); - pc.doConfigure(configFile, repo); - pc.dumpErrors(); - } - - Logger logger = Logger.getLogger(SimpleLog.class); - int i = 0; - - logger.debug("This message number: " + (i++)); - logger.debug("This message number: " + (i++)); - logger.error("This message number: " + (i++), new Exception("Bogus.")); - } - - static void usage(String msg) { - System.err.println(msg); - System.err.println( - "Usage: java " + SimpleLog.class.getName() + " configFile\n" - + " configFile a log4j configuration file, either in properties " - + " or XML format. XML files must have a '.xml' extension."); - System.exit(1); - } -} diff --git a/tests/src/java/org/apache/log4j/StressCategory.java b/tests/src/java/org/apache/log4j/StressCategory.java index ad8d79c318..0cadf6f5f2 100644 --- a/tests/src/java/org/apache/log4j/StressCategory.java +++ b/tests/src/java/org/apache/log4j/StressCategory.java @@ -23,14 +23,13 @@ import java.util.Random; /* - Stress test the Category class. + Stress test the Logger class. */ class StressCategory { - static Level[] level = new Level[] {Level.TRACE, - Level.DEBUG, + static Level[] level = new Level[] {Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR, @@ -77,14 +76,15 @@ public static void main(String[] args) { // On each possible permutation call createLoop static void permute(int n) { - if(n == LENGTH) - createLoop(0); - else - for(int i = n; i < LENGTH; i++) { - swap(names, n, i); - permute(n+1); - swap(names, n, i); - } + if(n == LENGTH) { + createLoop(0); + } else { + for(int i = n; i < LENGTH; i++) { + swap(names, n, i); + permute(n+1); + swap(names, n, i); + } + } } static @@ -113,9 +113,9 @@ void createLoop(int n) { if(n == LENGTH) { //System.out.println("..............Creating cat[]..........."); for(int i = 0; i < LENGTH; i++) { - if(ct[i] == null) - cat[i] = null; - else { + if(ct[i] == null) { + cat[i] = null; + } else { cat[i] = Logger.getLogger(ct[i].catstr); cat[i].setLevel(ct[i].level); } @@ -132,7 +132,9 @@ void createLoop(int n) { ct[n] = new CT(names[n], null); createLoop(n+1); - int r = random.nextInt(); if(r < 0) r = -r; + int r = random.nextInt(); if(r < 0) { + r = -r; + } ct[n] = new CT(names[n], level[r%5]); createLoop(n+1); } @@ -161,32 +163,45 @@ void test() { static void ctDump() { for(int j = 0; j < LENGTH; j++) { - if(ct[j] != null) - System.out.println("ct [" + j + "] = ("+ct[j].catstr+"," + + if(ct[j] != null) { + System.out.println("ct [" + j + "] = ("+ct[j].catstr+"," + ct[j].level + ")"); - else - System.out.println("ct [" + j + "] = undefined"); + } else { + System.out.println("ct [" + j + "] = undefined"); + } } } static void catDump() { for(int j = 0; j < LENGTH; j++) { - if(cat[j] != null) - System.out.println("cat[" + j + "] = (" + cat[j].name + "," + - cat[j].getLevel() + ")"); - else - System.out.println("cat[" + j + "] = undefined"); + if(cat[j] != null) { + System.out.println("cat[" + j + "] = (" + cat[j].name + "," + + cat[j].getLevel() + ")"); + } else { + System.out.println("cat[" + j + "] = undefined"); + } } } + // static + //void provisionNodesDump() { + //for (Enumeration e = CategoryFactory.ht.keys(); e.hasMoreElements() ;) { + // CategoryKey key = (CategoryKey) e.nextElement(); + // Object c = CategoryFactory.ht.get(key); + // if(c instanceof ProvisionNode) + //((ProvisionNode) c).dump(key.name); + //} + //} + static boolean checkCorrectness(int i) { CT localCT = ct[i]; - // Can't perform test if category is not instantiated - if(localCT == null) - return true; + // Can't perform test if logger is not instantiated + if(localCT == null) { + return true; + } // find expected level Level expected = getExpectedPrioriy(localCT); @@ -207,8 +222,9 @@ boolean checkCorrectness(int i) { static Level getExpectedPrioriy(CT ctParam) { Level level = ctParam.level; - if(level != null) - return level; + if(level != null) { + return level; + } String catstr = ctParam.catstr; @@ -221,8 +237,9 @@ Level getExpectedPrioriy(CT ctParam) { for(int j = 0; j < LENGTH; j++) { if(ct[j] != null && substr.equals(ct[j].catstr)) { Level p = ct[j].level; - if(p != null) - return p; + if(p != null) { + return p; + } } } } @@ -241,5 +258,3 @@ static class CT { } } } - -// End of class: StressCategory.java diff --git a/tests/src/java/org/apache/log4j/TTCCLayoutTest.java b/tests/src/java/org/apache/log4j/TTCCLayoutTest.java index 5cea6ba1b0..35f6d1ec06 100644 --- a/tests/src/java/org/apache/log4j/TTCCLayoutTest.java +++ b/tests/src/java/org/apache/log4j/TTCCLayoutTest.java @@ -17,16 +17,16 @@ package org.apache.log4j; +import org.apache.log4j.helpers.DateLayoutTest; import org.apache.log4j.spi.LoggingEvent; /** * Test for TTCCLayout. - * @deprecated Since TTCCLayoutTest is deprecated * * @author Curt Arnold */ -public class TTCCLayoutTest extends org.apache.log4j.helpers.DateLayoutTest { +public class TTCCLayoutTest extends DateLayoutTest { /** * Construct new instance of TTCCLayoutTest. * @@ -38,7 +38,6 @@ public TTCCLayoutTest(final String testName) { /** * @{inheritDoc} - * @deprecated since TTCCLayout is deprecated. */ protected Layout createLayout() { return new TTCCLayout(); @@ -46,7 +45,6 @@ protected Layout createLayout() { /** * Tests format. - * @deprecated since TTCCLayout is deprecated. */ public void testFormat() { NDC.clear(); @@ -78,7 +76,6 @@ public void testFormat() { /** * Tests getThreadPrinting and setThreadPrinting. - * @deprecated since TTCCLayout is deprecated. */ public void testGetSetThreadPrinting() { TTCCLayout layout = new TTCCLayout(); @@ -91,7 +88,6 @@ public void testGetSetThreadPrinting() { /** * Tests getCategoryPrefixing and setCategoryPrefixing. - * @deprecated since TTCCLayout is deprecated. */ public void testGetSetCategoryPrefixing() { TTCCLayout layout = new TTCCLayout(); @@ -104,7 +100,6 @@ public void testGetSetCategoryPrefixing() { /** * Tests getContextPrinting and setContextPrinting. - * @deprecated since TTCCLayout is deprecated. */ public void testGetSetContextPrinting() { TTCCLayout layout = new TTCCLayout(); diff --git a/tests/src/java/org/apache/log4j/TestLogMF.java b/tests/src/java/org/apache/log4j/TestLogMF.java new file mode 100755 index 0000000000..9adff211c0 --- /dev/null +++ b/tests/src/java/org/apache/log4j/TestLogMF.java @@ -0,0 +1,1291 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j; + +import junit.framework.TestCase; + +import java.io.CharArrayWriter; +import java.text.MessageFormat; +import java.text.NumberFormat; +import java.util.Date; +import java.text.DateFormat; + + +/** + * Unit test for LogMF. + */ +public class TestLogMF extends TestCase { + /** + * Trace level. + */ + private static final Level TRACE = getTraceLevel(); + + /** + * Gets Trace level. + * Trace level was not defined prior to log4j 1.2.12. + * @return trace level + */ + private static Level getTraceLevel() { + try { + return (Level) Level.class.getField("TRACE").get(null); + } catch(Exception ex) { + return new Level(5000, "TRACE", 7); + } + } + + /** + * Logger. + */ + private final Logger logger = Logger.getLogger( + "org.apache.log4j.formatter.TestLogMF"); + + /** + * Create the test case + * + * @param testName name of the test case + */ + public TestLogMF(String testName) { + super(testName); + } + + + /** + * Post test clean up. + */ + public void tearDown() { + LogManager.resetConfiguration(); + } + + /** + * Test class name when logging through LogMF. + */ + public void testClassName() { + CharArrayWriter writer = new CharArrayWriter(); + PatternLayout layout = new PatternLayout("%C"); + WriterAppender appender = new WriterAppender(layout, writer); + appender.activateOptions(); + Logger.getRootLogger().addAppender(appender); + LogMF.debug(logger, null, Math.PI); + assertEquals(TestLogMF.class.getName(), writer.toString()); + } + + /** + * Test LogMF.trace with null pattern. + */ + public void testTraceNullPattern() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogMF.trace(logger, null, Math.PI); + assertNull(capture.getMessage()); + } + + /** + * Test LogMF.trace with no-field pattern. + */ + public void testTraceNoArg() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogMF.trace(logger, "Hello, World", Math.PI); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogMF.trace with malformed pattern. + */ + public void testTraceBadPattern() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogMF.trace(logger, "Hello, {.", Math.PI); + assertEquals("Hello, {.", capture.getMessage()); + } + + /** + * Test LogMF.trace with missing argument. + */ + public void testTraceMissingArg() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogMF.trace(logger, "Hello, {0}World", new Object[0]); + assertEquals("Hello, {0}World", capture.getMessage()); + } + + /** + * Test LogMF.trace with single field pattern with string argument. + */ + public void testTraceString() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogMF.trace(logger, "Hello, {0}", "World"); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogMF.trace with single field pattern with null argument. + */ + public void testTraceNull() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogMF.trace(logger, "Hello, {0}", (Object) null); + assertEquals("Hello, null", capture.getMessage()); + } + + /** + * Test LogMF.trace with single field pattern with int argument. + */ + public void testTraceInt() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + + int val = 42; + LogMF.trace(logger, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.trace with single field pattern with byte argument. + */ + public void testTraceByte() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + + byte val = 42; + LogMF.trace(logger, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.trace with single field pattern with short argument. + */ + public void testTraceShort() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + + short val = 42; + LogMF.trace(logger, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.trace with single field pattern with long argument. + */ + public void testTraceLong() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + + long val = 42; + LogMF.trace(logger, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.trace with single field pattern with char argument. + */ + public void testTraceChar() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + + char val = 'C'; + LogMF.trace(logger, "Iteration {0}", val); + assertEquals("Iteration C", capture.getMessage()); + } + + /** + * Test LogMF.trace with single field pattern with boolean argument. + */ + public void testTraceBoolean() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + + boolean val = true; + LogMF.trace(logger, "Iteration {0}", val); + assertEquals("Iteration true", capture.getMessage()); + } + + /** + * Test LogMF.trace with single field pattern with float argument. + */ + public void testTraceFloat() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + + float val = 3.14f; + NumberFormat format = NumberFormat.getInstance(); + LogMF.trace(logger, "Iteration {0}", val); + assertEquals("Iteration "+ format.format(val), capture.getMessage()); + } + + /** + * Test LogMF.trace with single field pattern with double argument. + */ + public void testTraceDouble() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + + double val = 3.14; + NumberFormat format = NumberFormat.getInstance(); + LogMF.trace(logger, "Iteration {0}", val); + assertEquals("Iteration "+ format.format(val), capture.getMessage()); + } + + /** + * Test LogMF.trace with two arguments. + */ + public void testTraceTwoArg() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogMF.trace(logger, "{1}, {0}.", "World", "Hello"); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.trace with three arguments. + */ + public void testTraceThreeArg() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogMF.trace(logger, "{1}{2} {0}.", "World", "Hello", ","); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.trace with four arguments. + */ + public void testTraceFourArg() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogMF.trace(logger, "{1}{2} {0}{3}", "World", "Hello", ",", "."); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.trace with Object[] argument. + */ + public void testTraceArrayArg() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + + Object[] args = new Object[] { "World", "Hello", ",", "." }; + LogMF.trace(logger, "{1}{2} {0}{3}", args); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.trace with null Object[] argument. + */ + public void testTraceNullArrayArg() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + + Object[] args = null; + LogMF.trace(logger, "{1}{2} {0}{3}", args); + assertEquals("{1}{2} {0}{3}", capture.getMessage()); + } + + + /** + * Test LogMF.debug with null pattern. + */ + public void testDebugNullPattern() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogMF.debug(logger, null, Math.PI); + assertEquals(null, capture.getMessage()); + } + + /** + * Test LogMF.debug with no-field pattern. + */ + public void testDebugNoArg() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogMF.debug(logger, "Hello, World", Math.PI); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogMF.debug with malformed pattern. + */ + public void testDebugBadPattern() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogMF.debug(logger, "Hello, {.", Math.PI); + assertEquals("Hello, {.", capture.getMessage()); + } + + /** + * Test LogMF.debug with missing argument. + */ + public void testDebugMissingArg() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogMF.debug(logger, "Hello, {0}World", new Object[0]); + assertEquals("Hello, {0}World", capture.getMessage()); + } + + /** + * Test LogMF.debug with single field pattern with string argument. + */ + public void testDebugString() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogMF.debug(logger, "Hello, {0}", "World"); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogMF.debug with single field pattern with null argument. + */ + public void testDebugNull() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogMF.debug(logger, "Hello, {0}", (Object) null); + assertEquals("Hello, null", capture.getMessage()); + } + + /** + * Test LogMF.debug with single field pattern with int argument. + */ + public void testDebugInt() { + LogCapture capture = new LogCapture(Level.DEBUG); + int val = 42; + LogMF.debug(logger, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.debug with single field pattern with byte argument. + */ + public void testDebugByte() { + LogCapture capture = new LogCapture(Level.DEBUG); + byte val = 42; + LogMF.debug(logger, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.debug with single field pattern with short argument. + */ + public void testDebugShort() { + LogCapture capture = new LogCapture(Level.DEBUG); + short val = 42; + LogMF.debug(logger, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.debug with single field pattern with long argument. + */ + public void testDebugLong() { + LogCapture capture = new LogCapture(Level.DEBUG); + long val = 42; + LogMF.debug(logger, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.debug with single field pattern with char argument. + */ + public void testDebugChar() { + LogCapture capture = new LogCapture(Level.DEBUG); + char val = 'C'; + LogMF.debug(logger, "Iteration {0}", val); + assertEquals("Iteration C", capture.getMessage()); + } + + /** + * Test LogMF.debug with single field pattern with boolean argument. + */ + public void testDebugBoolean() { + LogCapture capture = new LogCapture(Level.DEBUG); + boolean val = true; + LogMF.debug(logger, "Iteration {0}", val); + assertEquals("Iteration true", capture.getMessage()); + } + + /** + * Test LogMF.debug with single field pattern with float argument. + */ + public void testDebugFloat() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogMF.debug(logger, "Iteration {0}", (float) Math.PI); + + String expected = MessageFormat.format("Iteration {0}", + new Object[] { new Float(Math.PI) }); + assertEquals(expected, capture.getMessage()); + } + + /** + * Test LogMF.debug with single field pattern with double argument. + */ + public void testDebugDouble() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogMF.debug(logger, "Iteration {0}", Math.PI); + + String expected = MessageFormat.format("Iteration {0}", + new Object[] { new Double(Math.PI) }); + assertEquals(expected, capture.getMessage()); + } + + /** + * Test LogMF.debug with two arguments. + */ + public void testDebugTwoArg() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogMF.debug(logger, "{1}, {0}.", "World", "Hello"); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.debug with three arguments. + */ + public void testDebugThreeArg() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogMF.debug(logger, "{1}{2} {0}.", "World", "Hello", ","); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.debug with four arguments. + */ + public void testDebugFourArg() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogMF.debug(logger, "{1}{2} {0}{3}", "World", "Hello", ",", "."); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.debug with Object[] argument. + */ + public void testDebugArrayArg() { + LogCapture capture = new LogCapture(Level.DEBUG); + Object[] args = new Object[] { "World", "Hello", ",", "." }; + LogMF.debug(logger, "{1}{2} {0}{3}", args); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.debug with single field pattern with double argument. + */ + public void testDebugDate() { + LogCapture capture = new LogCapture(Level.DEBUG); + Date epoch = new Date(0); + LogMF.debug(logger, "Iteration {0}", epoch); + + String expected = MessageFormat.format("Iteration {0}", + new Object[] { epoch }); + String expected2 = "Iteration " + DateFormat.getDateTimeInstance( + DateFormat.SHORT, + DateFormat.SHORT).format(epoch); + String actual = capture.getMessage(); + // + // gcj has been observed to output 12/31/69 6:00:00 PM + // instead of the expected 12/31/69 6:00 PM + if (System.getProperty("java.vendor").indexOf("Free") == -1) { + assertEquals(expected, actual); + } + assertEquals(expected2, actual); + } + + /** + * Test LogMF.debug with null Object[] argument. + */ + public void testDebugNullArrayArg() { + LogCapture capture = new LogCapture(Level.DEBUG); + Object[] args = null; + LogMF.debug(logger, "{1}{2} {0}{3}", args); + assertEquals("{1}{2} {0}{3}", capture.getMessage()); + } + + public void testDebugPercent() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogMF.debug(logger, "{0, number, percent}", Math.PI); + + String expected = java.text.MessageFormat.format("{0, number, percent}", + new Object[] { new Double(Math.PI) }); + assertEquals(expected, capture.getMessage()); + } + + public void testDebugFullPrecisionAndPercent() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogMF.debug(logger, "{0}{0, number, percent}", Math.PI); + + String expected = java.text.MessageFormat.format("{0}{0, number, percent}", + new Object[] { new Double(Math.PI) }); + assertEquals(expected, capture.getMessage()); + } + + public void testDebugQuoted() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogMF.debug(logger, "'{0}'", "World"); + assertEquals("{0}", capture.getMessage()); + } + + /** + * Test LogMF.info with null pattern. + */ + public void testInfoNullPattern() { + LogCapture capture = new LogCapture(Level.INFO); + LogMF.info(logger, null, Math.PI); + assertNull(capture.getMessage()); + } + + /** + * Test LogMF.info with no-field pattern. + */ + public void testInfoNoArg() { + LogCapture capture = new LogCapture(Level.INFO); + LogMF.info(logger, "Hello, World", Math.PI); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogMF.info with malformed pattern. + */ + public void testInfoBadPattern() { + LogCapture capture = new LogCapture(Level.INFO); + LogMF.info(logger, "Hello, {.", Math.PI); + assertEquals("Hello, {.", capture.getMessage()); + } + + /** + * Test LogMF.info with missing argument. + */ + public void testInfoMissingArg() { + LogCapture capture = new LogCapture(Level.INFO); + LogMF.info(logger, "Hello, {0}World", new Object[0]); + assertEquals("Hello, {0}World", capture.getMessage()); + } + + /** + * Test LogMF.info with single field pattern with string argument. + */ + public void testInfoString() { + LogCapture capture = new LogCapture(Level.INFO); + LogMF.info(logger, "Hello, {0}", "World"); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogMF.info with single field pattern with null argument. + */ + public void testInfoNull() { + LogCapture capture = new LogCapture(Level.INFO); + LogMF.info(logger, "Hello, {0}", (Object) null); + assertEquals("Hello, null", capture.getMessage()); + } + + /** + * Test LogMF.info with single field pattern with int argument. + */ + public void testInfoInt() { + LogCapture capture = new LogCapture(Level.INFO); + int val = 42; + LogMF.info(logger, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.info with single field pattern with byte argument. + */ + public void testInfoByte() { + LogCapture capture = new LogCapture(Level.INFO); + byte val = 42; + LogMF.info(logger, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.info with single field pattern with short argument. + */ + public void testInfoShort() { + LogCapture capture = new LogCapture(Level.INFO); + short val = 42; + LogMF.info(logger, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.info with single field pattern with long argument. + */ + public void testInfoLong() { + LogCapture capture = new LogCapture(Level.INFO); + long val = 42; + LogMF.info(logger, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.info with single field pattern with char argument. + */ + public void testInfoChar() { + LogCapture capture = new LogCapture(Level.INFO); + char val = 'C'; + LogMF.info(logger, "Iteration {0}", val); + assertEquals("Iteration C", capture.getMessage()); + } + + /** + * Test LogMF.info with single field pattern with boolean argument. + */ + public void testInfoBoolean() { + LogCapture capture = new LogCapture(Level.INFO); + boolean val = true; + LogMF.info(logger, "Iteration {0}", val); + assertEquals("Iteration true", capture.getMessage()); + } + + /** + * Test LogMF.info with single field pattern with float argument. + */ + public void testInfoFloat() { + LogCapture capture = new LogCapture(Level.INFO); + LogMF.info(logger, "Iteration {0}", (float) Math.PI); + + String expected = MessageFormat.format("Iteration {0}", + new Object[] { new Float(Math.PI) }); + assertEquals(expected, capture.getMessage()); + } + + /** + * Test LogMF.info with single field pattern with double argument. + */ + public void testInfoDouble() { + LogCapture capture = new LogCapture(Level.INFO); + LogMF.info(logger, "Iteration {0}", Math.PI); + + String expected = MessageFormat.format("Iteration {0}", + new Object[] { new Double(Math.PI) }); + assertEquals(expected, capture.getMessage()); + } + + /** + * Test LogMF.info with two arguments. + */ + public void testInfoTwoArg() { + LogCapture capture = new LogCapture(Level.INFO); + LogMF.info(logger, "{1}, {0}.", "World", "Hello"); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.info with three arguments. + */ + public void testInfoThreeArg() { + LogCapture capture = new LogCapture(Level.INFO); + LogMF.info(logger, "{1}{2} {0}.", "World", "Hello", ","); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.info with four arguments. + */ + public void testInfoFourArg() { + LogCapture capture = new LogCapture(Level.INFO); + LogMF.info(logger, "{1}{2} {0}{3}", "World", "Hello", ",", "."); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.info with Object[] argument. + */ + public void testInfoArrayArg() { + LogCapture capture = new LogCapture(Level.INFO); + Object[] args = new Object[] { "World", "Hello", ",", "." }; + LogMF.info(logger, "{1}{2} {0}{3}", args); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.warn with null pattern. + */ + public void testWarnNullPattern() { + LogCapture capture = new LogCapture(Level.WARN); + LogMF.warn(logger, null, Math.PI); + assertNull(capture.getMessage()); + } + + /** + * Test LogMF.warn with no-field pattern. + */ + public void testWarnNoArg() { + LogCapture capture = new LogCapture(Level.WARN); + LogMF.warn(logger, "Hello, World", Math.PI); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogMF.warn with malformed pattern. + */ + public void testWarnBadPattern() { + LogCapture capture = new LogCapture(Level.WARN); + LogMF.warn(logger, "Hello, {.", Math.PI); + assertEquals("Hello, {.", capture.getMessage()); + } + + /** + * Test LogMF.warn with missing argument. + */ + public void testWarnMissingArg() { + LogCapture capture = new LogCapture(Level.WARN); + LogMF.warn(logger, "Hello, {0}World", new Object[0]); + assertEquals("Hello, {0}World", capture.getMessage()); + } + + /** + * Test LogMF.warn with single field pattern with string argument. + */ + public void testWarnString() { + LogCapture capture = new LogCapture(Level.WARN); + LogMF.warn(logger, "Hello, {0}", "World"); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogMF.warn with single field pattern with null argument. + */ + public void testWarnNull() { + LogCapture capture = new LogCapture(Level.WARN); + LogMF.warn(logger, "Hello, {0}", (Object) null); + assertEquals("Hello, null", capture.getMessage()); + } + + /** + * Test LogMF.warn with single field pattern with int argument. + */ + public void testWarnInt() { + LogCapture capture = new LogCapture(Level.WARN); + int val = 42; + LogMF.warn(logger, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.warn with single field pattern with byte argument. + */ + public void testWarnByte() { + LogCapture capture = new LogCapture(Level.WARN); + byte val = 42; + LogMF.warn(logger, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.warn with single field pattern with short argument. + */ + public void testWarnShort() { + LogCapture capture = new LogCapture(Level.WARN); + short val = 42; + LogMF.warn(logger, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.warn with single field pattern with long argument. + */ + public void testWarnLong() { + LogCapture capture = new LogCapture(Level.WARN); + long val = 42; + LogMF.warn(logger, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.warn with single field pattern with char argument. + */ + public void testWarnChar() { + LogCapture capture = new LogCapture(Level.WARN); + char val = 'C'; + LogMF.warn(logger, "Iteration {0}", val); + assertEquals("Iteration C", capture.getMessage()); + } + + /** + * Test LogMF.warn with single field pattern with boolean argument. + */ + public void testWarnBoolean() { + LogCapture capture = new LogCapture(Level.WARN); + boolean val = true; + LogMF.warn(logger, "Iteration {0}", val); + assertEquals("Iteration true", capture.getMessage()); + } + + /** + * Test LogMF.warn with single field pattern with float argument. + */ + public void testWarnFloat() { + LogCapture capture = new LogCapture(Level.WARN); + LogMF.warn(logger, "Iteration {0}", (float) Math.PI); + + String expected = MessageFormat.format("Iteration {0}", + new Object[] { new Float(Math.PI) }); + assertEquals(expected, capture.getMessage()); + } + + /** + * Test LogMF.debug with single field pattern with double argument. + */ + public void testWarnDouble() { + LogCapture capture = new LogCapture(Level.WARN); + LogMF.warn(logger, "Iteration {0}", Math.PI); + + String expected = MessageFormat.format("Iteration {0}", + new Object[] { new Double(Math.PI) }); + assertEquals(expected, capture.getMessage()); + } + + /** + * Test LogMF.warn with two arguments. + */ + public void testWarnTwoArg() { + LogCapture capture = new LogCapture(Level.WARN); + LogMF.warn(logger, "{1}, {0}.", "World", "Hello"); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.warn with three arguments. + */ + public void testWarnThreeArg() { + LogCapture capture = new LogCapture(Level.WARN); + LogMF.warn(logger, "{1}{2} {0}.", "World", "Hello", ","); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.debug with four arguments. + */ + public void testWarnFourArg() { + LogCapture capture = new LogCapture(Level.WARN); + LogMF.warn(logger, "{1}{2} {0}{3}", "World", "Hello", ",", "."); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.warn with Object[] argument. + */ + public void testWarnArrayArg() { + LogCapture capture = new LogCapture(Level.WARN); + Object[] args = new Object[] { "World", "Hello", ",", "." }; + LogMF.warn(logger, "{1}{2} {0}{3}", args); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.log with null pattern. + */ + public void testLogNullPattern() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.log(logger, Level.ERROR, null, Math.PI); + assertNull(capture.getMessage()); + } + + /** + * Test LogMF.log with no-field pattern. + */ + public void testLogNoArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.log(logger, Level.ERROR, "Hello, World", Math.PI); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogMF.log with malformed pattern. + */ + public void testLogBadPattern() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.log(logger, Level.ERROR, "Hello, {.", Math.PI); + assertEquals("Hello, {.", capture.getMessage()); + } + + /** + * Test LogMF.log with missing argument. + */ + public void testLogMissingArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.log(logger, Level.ERROR, "Hello, {0}World", new Object[0]); + assertEquals("Hello, {0}World", capture.getMessage()); + } + + /** + * Test LogMF.log with single field pattern with string argument. + */ + public void testLogString() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.log(logger, Level.ERROR, "Hello, {0}", "World"); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogMF.log with single field pattern with null argument. + */ + public void testLogNull() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.log(logger, Level.ERROR, "Hello, {0}", (Object) null); + assertEquals("Hello, null", capture.getMessage()); + } + + /** + * Test LogMF.log with single field pattern with int argument. + */ + public void testLogInt() { + LogCapture capture = new LogCapture(Level.ERROR); + int val = 42; + LogMF.log(logger, Level.ERROR, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.log with single field pattern with byte argument. + */ + public void testLogByte() { + LogCapture capture = new LogCapture(Level.ERROR); + byte val = 42; + LogMF.log(logger, Level.ERROR, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.log with single field pattern with short argument. + */ + public void testLogShort() { + LogCapture capture = new LogCapture(Level.ERROR); + short val = 42; + LogMF.log(logger, Level.ERROR, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.log with single field pattern with long argument. + */ + public void testLogLong() { + LogCapture capture = new LogCapture(Level.ERROR); + long val = 42; + LogMF.log(logger, Level.ERROR, "Iteration {0}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.log with single field pattern with char argument. + */ + public void testLogChar() { + LogCapture capture = new LogCapture(Level.ERROR); + char val = 'C'; + LogMF.log(logger, Level.ERROR, "Iteration {0}", val); + assertEquals("Iteration C", capture.getMessage()); + } + + /** + * Test LogMF.log with single field pattern with boolean argument. + */ + public void testLogBoolean() { + LogCapture capture = new LogCapture(Level.ERROR); + boolean val = true; + LogMF.log(logger, Level.ERROR, "Iteration {0}", val); + assertEquals("Iteration true", capture.getMessage()); + } + + /** + * Test LogMF.log with single field pattern with float argument. + */ + public void testLogFloat() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.log(logger, Level.ERROR, "Iteration {0}", (float) Math.PI); + + String expected = MessageFormat.format("Iteration {0}", + new Object[] { new Float(Math.PI) }); + assertEquals(expected, capture.getMessage()); + } + + /** + * Test LogMF.log with single field pattern with double argument. + */ + public void testLogDouble() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.log(logger, Level.ERROR, "Iteration {0}", Math.PI); + + String expected = MessageFormat.format("Iteration {0}", + new Object[] { new Double(Math.PI) }); + assertEquals(expected, capture.getMessage()); + } + + /** + * Test LogMF.log with two arguments. + */ + public void testLogTwoArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.log(logger, Level.ERROR, "{1}, {0}.", "World", "Hello"); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.log with three arguments. + */ + public void testLogThreeArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.log(logger, Level.ERROR, "{1}{2} {0}.", "World", "Hello", ","); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.log with four arguments. + */ + public void testLogFourArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.log(logger, Level.ERROR, "{1}{2} {0}{3}", "World", "Hello", ",", "."); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.log with Object[] argument. + */ + public void testLogArrayArg() { + LogCapture capture = new LogCapture(Level.ERROR); + Object[] args = new Object[] { "World", "Hello", ",", "." }; + LogMF.log(logger, Level.ERROR, "{1}{2} {0}{3}", args); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Bundle name for resource bundle tests. + */ + private static final String BUNDLE_NAME = + "org.apache.log4j.TestLogMFPatterns"; + + /** + * Test LogMF.logrb with null bundle name. + */ + public void testLogrbNullBundle() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.logrb(logger, Level.ERROR, null, "Iteration0", Math.PI); + assertEquals("Iteration0", capture.getMessage()); + } + + /** + * Test LogMF.logrb with null key. + */ + public void testLogrbNullKey() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.logrb(logger, Level.ERROR, BUNDLE_NAME, null, Math.PI); + assertNull(capture.getMessage()); + } + + /** + * Test LogMF.logrb with no-field pattern. + */ + public void testLogrbNoArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Hello1", Math.PI); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogMF.logrb with malformed pattern. + */ + public void testLogrbBadPattern() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Malformed", Math.PI); + assertEquals("Hello, {.", capture.getMessage()); + } + + /** + * Test LogMF.logrb with missing argument. + */ + public void testLogrbMissingArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Hello2", new Object[0]); + assertEquals("Hello, {0}World", capture.getMessage()); + } + + /** + * Test LogMF.logrb with single field pattern with string argument. + */ + public void testLogrbString() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Hello3", "World"); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogMF.logrb with single field pattern with null argument. + */ + public void testLogrbNull() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Hello3", (Object) null); + assertEquals("Hello, null", capture.getMessage()); + } + + /** + * Test LogMF.logrb with single field pattern with int argument. + */ + public void testLogrbInt() { + LogCapture capture = new LogCapture(Level.ERROR); + int val = 42; + LogMF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Iteration0", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.logrb with single field pattern with byte argument. + */ + public void testLogrbByte() { + LogCapture capture = new LogCapture(Level.ERROR); + byte val = 42; + LogMF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Iteration0", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.logrb with single field pattern with short argument. + */ + public void testLogrbShort() { + LogCapture capture = new LogCapture(Level.ERROR); + short val = 42; + LogMF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Iteration0", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.logrb with single field pattern with long argument. + */ + public void testLogrbLong() { + LogCapture capture = new LogCapture(Level.ERROR); + long val = 42; + LogMF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Iteration0", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogMF.logrb with single field pattern with char argument. + */ + public void testLogrbChar() { + LogCapture capture = new LogCapture(Level.ERROR); + char val = 'C'; + LogMF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Iteration0", val); + assertEquals("Iteration C", capture.getMessage()); + } + + /** + * Test LogMF.logrb with single field pattern with boolean argument. + */ + public void testLogrbBoolean() { + LogCapture capture = new LogCapture(Level.ERROR); + boolean val = true; + LogMF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Iteration0", val); + assertEquals("Iteration true", capture.getMessage()); + } + + /** + * Test LogMF.logrb with single field pattern with float argument. + */ + public void testLogrbFloat() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Iteration0", (float) Math.PI); + + String expected = MessageFormat.format("Iteration {0}", + new Object[] { new Float(Math.PI) }); + assertEquals(expected, capture.getMessage()); + } + + /** + * Test LogMF.logrb with single field pattern with double argument. + */ + public void testLogrbDouble() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Iteration0", Math.PI); + + String expected = MessageFormat.format("Iteration {0}", + new Object[] { new Double(Math.PI) }); + assertEquals(expected, capture.getMessage()); + } + + /** + * Test LogMF.logrb with two arguments. + */ + public void testLogrbTwoArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.logrb(logger, Level.ERROR, + BUNDLE_NAME, "Hello4", "World", "Hello"); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.logrb with three arguments. + */ + public void testLogrbThreeArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.logrb(logger, Level.ERROR, + BUNDLE_NAME, "Hello5", "World", "Hello", ","); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.logrb with four arguments. + */ + public void testLogrbFourArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogMF.logrb(logger, Level.ERROR, + BUNDLE_NAME, "Hello6", "World", "Hello", ",", "."); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogMF.logrb with Object[] argument. + */ + public void testLogrbArrayArg() { + LogCapture capture = new LogCapture(Level.ERROR); + Object[] args = new Object[] { "World", "Hello", ",", "." }; + LogMF.logrb(logger, Level.ERROR, + BUNDLE_NAME, "Hello6", args); + assertEquals("Hello, World.", capture.getMessage()); + } + + + /** + * Test LogMF.info with a pattern containing {9} and one argument. + */ + public void testInfo1ParamBrace9() { + LogCapture capture = new LogCapture(Level.INFO); + LogMF.info(logger, "Hello, {9}{0}", "World"); + assertEquals("Hello, {9}World", capture.getMessage()); + } + + /** + * Test LogMF.info with a pattern containing {9} and two arguments. + */ + public void testInfo2ParamBrace9() { + LogCapture capture = new LogCapture(Level.INFO); + LogMF.info(logger, "{1}, {9}{0}", "World", "Hello"); + assertEquals("Hello, {9}World", capture.getMessage()); + } + + /** + * Test LogMF.info with a pattern containing {9} and two arguments. + */ + public void testInfo10ParamBrace9() { + LogCapture capture = new LogCapture(Level.INFO); + LogMF.info(logger, "{1}, {9}{0}", + new Object[] { "World", "Hello", null, null, null, + null, null, null, null, "New " }); + assertEquals("Hello, New World", capture.getMessage()); + } + + /** + * Test LogMF.info with indexes just outside of 0 to 9. + */ + public void testInfo1ParamBraceSlashColon() { + LogCapture capture = new LogCapture(Level.INFO); + String pattern = "Hello, {/}{0}{:}"; + LogMF.info(logger, pattern, "World"); + assertEquals(pattern, capture.getMessage()); + } + + +} diff --git a/tests/src/java/org/apache/log4j/TestLogSF.java b/tests/src/java/org/apache/log4j/TestLogSF.java new file mode 100755 index 0000000000..330cd9b5df --- /dev/null +++ b/tests/src/java/org/apache/log4j/TestLogSF.java @@ -0,0 +1,1191 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j; + +import junit.framework.TestCase; + +import java.io.CharArrayWriter; + + +/** + * Unit test for LogSF. + */ +public class TestLogSF extends TestCase { + /** + * Trace level. + */ + private static final Level TRACE = getTraceLevel(); + + /** + * Gets Trace level. + * Trace level was not defined prior to log4j 1.2.12. + * @return trace level + */ + private static Level getTraceLevel() { + try { + return (Level) Level.class.getField("TRACE").get(null); + } catch(Exception ex) { + return new Level(5000, "TRACE", 7); + } + } + + /** + * Logger. + */ + private final Logger logger = Logger.getLogger( + "org.apache.log4j.formatter.TestLogSF"); + + /** + * Create the test case + * + * @param testName name of the test case + */ + public TestLogSF(String testName) { + super(testName); + } + + + /** + * Post test clean up. + */ + public void tearDown() { + LogManager.resetConfiguration(); + } + + /** + * Test class name when logging through LogSF. + */ + public void testClassName() { + CharArrayWriter writer = new CharArrayWriter(); + PatternLayout layout = new PatternLayout("%C"); + WriterAppender appender = new WriterAppender(layout, writer); + appender.activateOptions(); + Logger.getRootLogger().addAppender(appender); + LogSF.debug(logger, null, Math.PI); + assertEquals(TestLogSF.class.getName(), writer.toString()); + } + + + + /** + * Test LogSF.trace with null pattern. + */ + public void testTraceNullPattern() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogSF.trace(logger, null, Math.PI); + assertNull(capture.getMessage()); + } + + /** + * Test LogSF.trace with no-field pattern. + */ + public void testTraceNoArg() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogSF.trace(logger, "Hello, World", Math.PI); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogSF.trace with malformed pattern. + */ + public void testTraceBadPattern() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogSF.trace(logger, "Hello, {.", Math.PI); + assertEquals("Hello, {.", capture.getMessage()); + } + + /** + * Test LogSF.trace with missing argument. + */ + public void testTraceMissingArg() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogSF.trace(logger, "Hello, {}World", new Object[0]); + assertEquals("Hello, {}World", capture.getMessage()); + } + + /** + * Test LogSF.trace with single field pattern with string argument. + */ + public void testTraceString() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogSF.trace(logger, "Hello, {}", "World"); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogSF.trace with single field pattern with null argument. + */ + public void testTraceNull() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogSF.trace(logger, "Hello, {}", (Object) null); + assertEquals("Hello, null", capture.getMessage()); + } + + /** + * Test LogSF.trace with single field pattern with int argument. + */ + public void testTraceInt() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + int val = 42; + LogSF.trace(logger, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.trace with single field pattern with byte argument. + */ + public void testTraceByte() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + byte val = 42; + LogSF.trace(logger, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.trace with single field pattern with short argument. + */ + public void testTraceShort() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + short val = 42; + LogSF.trace(logger, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.trace with single field pattern with long argument. + */ + public void testTraceLong() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + long val = 42; + LogSF.trace(logger, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.trace with single field pattern with char argument. + */ + public void testTraceChar() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + char val = 'C'; + LogSF.trace(logger, "Iteration {}", val); + assertEquals("Iteration C", capture.getMessage()); + } + + /** + * Test LogSF.trace with single field pattern with boolean argument. + */ + public void testTraceBoolean() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + boolean val = true; + LogSF.trace(logger, "Iteration {}", val); + assertEquals("Iteration true", capture.getMessage()); + } + + /** + * Test LogSF.trace with single field pattern with float argument. + */ + public void testTraceFloat() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + float val = 3.14f; + LogSF.trace(logger, "Iteration {}", val); + assertEquals("Iteration " + String.valueOf(val), capture.getMessage()); + } + + /** + * Test LogSF.trace with single field pattern with double argument. + */ + public void testTraceDouble() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + double val = 3.14; + LogSF.trace(logger, "Iteration {}", val); + assertEquals("Iteration " + String.valueOf(val), capture.getMessage()); + } + + /** + * Test LogSF.trace with two arguments. + */ + public void testTraceTwoArg() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogSF.trace(logger, "{}, {}.", "Hello", "World"); + assertEquals("Hello, World.", capture.getMessage()); + + } + + /** + * Test LogSF.trace with three arguments. + */ + public void testTraceThreeArg() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogSF.trace(logger, "{}{} {}.", "Hello", ",", "World"); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogSF.trace with Object[] argument. + */ + public void testTraceFourArg() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + LogSF.trace(logger, "{}{} {}{}", "Hello", ",", "World", "."); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogSF.trace with Object[] argument. + */ + public void testTraceArrayArg() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + Object[] args = new Object[] { "Hello", ",", "World", "." }; + LogSF.trace(logger, "{}{} {}{}", args); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogSF.trace with null Object[] argument. + */ + public void testTraceNullArrayArg() { + LogCapture capture = new LogCapture(TRACE); + logger.setLevel(TRACE); + Object[] args = null; + LogSF.trace(logger, "{}{} {}{}", args); + assertEquals("{}{} {}{}", capture.getMessage()); + } + + + + /** + * Test LogSF.debug with null pattern. + */ + public void testDebugNullPattern() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogSF.debug(logger, null, Math.PI); + assertNull(capture.getMessage()); + } + + /** + * Test LogSF.debug with no-field pattern. + */ + public void testDebugNoArg() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogSF.debug(logger, "Hello, World", Math.PI); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogSF.debug with malformed pattern. + */ + public void testDebugBadPattern() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogSF.debug(logger, "Hello, {.", Math.PI); + assertEquals("Hello, {.", capture.getMessage()); + } + + /** + * Test LogSF.debug with missing argument. + */ + public void testDebugMissingArg() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogSF.debug(logger, "Hello, {}World", new Object[0]); + assertEquals("Hello, {}World", capture.getMessage()); + } + + /** + * Test LogSF.debug with single field pattern with string argument. + */ + public void testDebugString() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogSF.debug(logger, "Hello, {}", "World"); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogSF.debug with single field pattern with null argument. + */ + public void testDebugNull() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogSF.debug(logger, "Hello, {}", (Object) null); + assertEquals("Hello, null", capture.getMessage()); + } + + /** + * Test LogSF.debug with single field pattern with int argument. + */ + public void testDebugInt() { + LogCapture capture = new LogCapture(Level.DEBUG); + int val = 42; + LogSF.debug(logger, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.debug with single field pattern with byte argument. + */ + public void testDebugByte() { + LogCapture capture = new LogCapture(Level.DEBUG); + byte val = 42; + LogSF.debug(logger, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.debug with single field pattern with short argument. + */ + public void testDebugShort() { + LogCapture capture = new LogCapture(Level.DEBUG); + short val = 42; + LogSF.debug(logger, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.debug with single field pattern with long argument. + */ + public void testDebugLong() { + LogCapture capture = new LogCapture(Level.DEBUG); + long val = 42; + LogSF.debug(logger, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.debug with single field pattern with char argument. + */ + public void testDebugChar() { + LogCapture capture = new LogCapture(Level.DEBUG); + char val = 'C'; + LogSF.debug(logger, "Iteration {}", val); + assertEquals("Iteration C", capture.getMessage()); + } + + /** + * Test LogSF.debug with single field pattern with boolean argument. + */ + public void testDebugBoolean() { + LogCapture capture = new LogCapture(Level.DEBUG); + boolean val = true; + LogSF.debug(logger, "Iteration {}", val); + assertEquals("Iteration true", capture.getMessage()); + } + + /** + * Test LogSF.debug with single field pattern with float argument. + */ + public void testDebugFloat() { + LogCapture capture = new LogCapture(Level.DEBUG); + float val = 3.14f; + LogSF.debug(logger, "Iteration {}", val); + assertEquals("Iteration " + String.valueOf(val), capture.getMessage()); + } + + /** + * Test LogSF.debug with single field pattern with double argument. + */ + public void testDebugDouble() { + LogCapture capture = new LogCapture(Level.DEBUG); + double val = 3.14; + LogSF.debug(logger, "Iteration {}", val); + assertEquals("Iteration " + String.valueOf(val), capture.getMessage()); + } + + /** + * Test LogSF.debug with two arguments. + */ + public void testDebugTwoArg() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogSF.debug(logger, "{}, {}.", "Hello", "World"); + assertEquals("Hello, World.", capture.getMessage()); + + } + + /** + * Test LogSF.debug with three arguments. + */ + public void testDebugThreeArg() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogSF.debug(logger, "{}{} {}.", "Hello", ",", "World"); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogSF.debug with four arguments. + */ + public void testDebugFourArg() { + LogCapture capture = new LogCapture(Level.DEBUG); + LogSF.debug(logger, "{}{} {}{}", "Hello", ",", "World", "."); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogSF.debug with Object[] argument. + */ + public void testDebugArrayArg() { + LogCapture capture = new LogCapture(Level.DEBUG); + Object[] args = new Object[] { "Hello", ",", "World", "." }; + LogSF.debug(logger, "{}{} {}{}", args); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogSF.debug with null Object[] argument. + */ + public void testDebugNullArrayArg() { + LogCapture capture = new LogCapture(Level.DEBUG); + Object[] args = null; + LogSF.debug(logger, "{}{} {}{}", args); + assertEquals("{}{} {}{}", capture.getMessage()); + } + + /** + * Test LogSF.info with null pattern. + */ + public void testInfoNullPattern() { + LogCapture capture = new LogCapture(Level.INFO); + LogSF.info(logger, null, Math.PI); + assertNull(capture.getMessage()); + } + + /** + * Test LogSF.info with no-field pattern. + */ + public void testInfoNoArg() { + LogCapture capture = new LogCapture(Level.INFO); + LogSF.info(logger, "Hello, World", Math.PI); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogSF.info with malformed pattern. + */ + public void testInfoBadPattern() { + LogCapture capture = new LogCapture(Level.INFO); + LogSF.info(logger, "Hello, {.", Math.PI); + assertEquals("Hello, {.", capture.getMessage()); + } + + /** + * Test LogSF.info with missing argument. + */ + public void testInfoMissingArg() { + LogCapture capture = new LogCapture(Level.INFO); + LogSF.info(logger, "Hello, {}World", new Object[0]); + assertEquals("Hello, {}World", capture.getMessage()); + } + + /** + * Test LogSF.info with single field pattern with string argument. + */ + public void testInfoString() { + LogCapture capture = new LogCapture(Level.INFO); + LogSF.info(logger, "Hello, {}", "World"); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogSF.info with single field pattern with null argument. + */ + public void testInfoNull() { + LogCapture capture = new LogCapture(Level.INFO); + LogSF.info(logger, "Hello, {}", (Object) null); + assertEquals("Hello, null", capture.getMessage()); + } + + /** + * Test LogSF.info with single field pattern with int argument. + */ + public void testInfoInt() { + LogCapture capture = new LogCapture(Level.INFO); + int val = 42; + LogSF.info(logger, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.info with single field pattern with byte argument. + */ + public void testInfoByte() { + LogCapture capture = new LogCapture(Level.INFO); + byte val = 42; + LogSF.info(logger, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.info with single field pattern with short argument. + */ + public void testInfoShort() { + LogCapture capture = new LogCapture(Level.INFO); + short val = 42; + LogSF.info(logger, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.info with single field pattern with long argument. + */ + public void testInfoLong() { + LogCapture capture = new LogCapture(Level.INFO); + long val = 42; + LogSF.info(logger, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.info with single field pattern with char argument. + */ + public void testInfoChar() { + LogCapture capture = new LogCapture(Level.INFO); + char val = 'C'; + LogSF.info(logger, "Iteration {}", val); + assertEquals("Iteration C", capture.getMessage()); + } + + /** + * Test LogSF.info with single field pattern with boolean argument. + */ + public void testInfoBoolean() { + LogCapture capture = new LogCapture(Level.INFO); + boolean val = true; + LogSF.info(logger, "Iteration {}", val); + assertEquals("Iteration true", capture.getMessage()); + } + + /** + * Test LogSF.info with single field pattern with float argument. + */ + public void testInfoFloat() { + LogCapture capture = new LogCapture(Level.INFO); + float val = 3.14f; + LogSF.info(logger, "Iteration {}", val); + assertEquals("Iteration " + String.valueOf(val), capture.getMessage()); + } + + /** + * Test LogSF.info with single field pattern with double argument. + */ + public void testInfoDouble() { + LogCapture capture = new LogCapture(Level.INFO); + double val = 3.14; + LogSF.info(logger, "Iteration {}", val); + assertEquals("Iteration " + String.valueOf(val), capture.getMessage()); + } + + /** + * Test LogSF.info with two arguments. + */ + public void testInfoTwoArg() { + LogCapture capture = new LogCapture(Level.INFO); + LogSF.info(logger, "{}, {}.", "Hello", "World"); + assertEquals("Hello, World.", capture.getMessage()); + + } + + /** + * Test LogSF.info with three arguments. + */ + public void testInfoThreeArg() { + LogCapture capture = new LogCapture(Level.INFO); + LogSF.info(logger, "{}{} {}.", "Hello", ",", "World"); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogSF.info with Object[] argument. + */ + public void testInfoArrayArg() { + LogCapture capture = new LogCapture(Level.INFO); + Object[] args = new Object[] { "Hello", ",", "World", "." }; + LogSF.info(logger, "{}{} {}{}", args); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogSF.warn with null pattern. + */ + public void testWarnNullPattern() { + LogCapture capture = new LogCapture(Level.WARN); + LogSF.warn(logger, null, Math.PI); + assertNull(capture.getMessage()); + } + + /** + * Test LogSF.warn with no-field pattern. + */ + public void testWarnNoArg() { + LogCapture capture = new LogCapture(Level.WARN); + LogSF.warn(logger, "Hello, World", Math.PI); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogSF.warn with malformed pattern. + */ + public void testWarnBadPattern() { + LogCapture capture = new LogCapture(Level.WARN); + LogSF.warn(logger, "Hello, {.", Math.PI); + assertEquals("Hello, {.", capture.getMessage()); + } + + /** + * Test LogSF.warn with missing argument. + */ + public void testWarnMissingArg() { + LogCapture capture = new LogCapture(Level.WARN); + LogSF.warn(logger, "Hello, {}World", new Object[0]); + assertEquals("Hello, {}World", capture.getMessage()); + } + + /** + * Test LogSF.warn with single field pattern with string argument. + */ + public void testWarnString() { + LogCapture capture = new LogCapture(Level.WARN); + LogSF.warn(logger, "Hello, {}", "World"); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogSF.warn with single field pattern with null argument. + */ + public void testWarnNull() { + LogCapture capture = new LogCapture(Level.WARN); + LogSF.warn(logger, "Hello, {}", (Object) null); + assertEquals("Hello, null", capture.getMessage()); + } + + /** + * Test LogSF.warn with single field pattern with int argument. + */ + public void testWarnInt() { + LogCapture capture = new LogCapture(Level.WARN); + int val = 42; + LogSF.warn(logger, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.warn with single field pattern with byte argument. + */ + public void testWarnByte() { + LogCapture capture = new LogCapture(Level.WARN); + byte val = 42; + LogSF.warn(logger, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.warn with single field pattern with short argument. + */ + public void testWarnShort() { + LogCapture capture = new LogCapture(Level.WARN); + short val = 42; + LogSF.warn(logger, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.warn with single field pattern with long argument. + */ + public void testWarnLong() { + LogCapture capture = new LogCapture(Level.WARN); + long val = 42; + LogSF.warn(logger, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.warn with single field pattern with char argument. + */ + public void testWarnChar() { + LogCapture capture = new LogCapture(Level.WARN); + char val = 'C'; + LogSF.warn(logger, "Iteration {}", val); + assertEquals("Iteration C", capture.getMessage()); + } + + /** + * Test LogSF.warn with single field pattern with boolean argument. + */ + public void testWarnBoolean() { + LogCapture capture = new LogCapture(Level.WARN); + boolean val = true; + LogSF.warn(logger, "Iteration {}", val); + assertEquals("Iteration true", capture.getMessage()); + } + + /** + * Test LogSF.warn with single field pattern with float argument. + */ + public void testWarnFloat() { + LogCapture capture = new LogCapture(Level.WARN); + float val = 3.14f; + LogSF.warn(logger, "Iteration {}", val); + assertEquals("Iteration " + String.valueOf(val), capture.getMessage()); + } + + /** + * Test LogSF.warn with single field pattern with double argument. + */ + public void testWarnDouble() { + LogCapture capture = new LogCapture(Level.WARN); + double val = 3.14; + LogSF.warn(logger, "Iteration {}", val); + assertEquals("Iteration " + String.valueOf(val), capture.getMessage()); + } + + /** + * Test LogSF.warn with two arguments. + */ + public void testWarnTwoArg() { + LogCapture capture = new LogCapture(Level.WARN); + LogSF.warn(logger, "{}, {}.", "Hello", "World"); + assertEquals("Hello, World.", capture.getMessage()); + + } + + /** + * Test LogSF.warn with three arguments. + */ + public void testWarnThreeArg() { + LogCapture capture = new LogCapture(Level.WARN); + LogSF.warn(logger, "{}{} {}.", "Hello", ",", "World"); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogSF.warn with Object[] argument. + */ + public void testWarnFourArg() { + LogCapture capture = new LogCapture(Level.WARN); + LogSF.warn(logger, "{}{} {}{}", + "Hello", ",", "World", "." ); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogSF.warn with Object[] argument. + */ + public void testWarnArrayArg() { + LogCapture capture = new LogCapture(Level.WARN); + Object[] args = new Object[] { "Hello", ",", "World", "." }; + LogSF.warn(logger, "{}{} {}{}", args); + assertEquals("Hello, World.", capture.getMessage()); + } + + + /** + * Test LogSF.log with null pattern. + */ + public void testLogNullPattern() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.log(logger, Level.ERROR, null, Math.PI); + assertNull(capture.getMessage()); + } + + /** + * Test LogSF.log with no-field pattern. + */ + public void testLogNoArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.log(logger, Level.ERROR, "Hello, World", Math.PI); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogSF.log with malformed pattern. + */ + public void testLogBadPattern() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.log(logger, Level.ERROR, "Hello, {.", Math.PI); + assertEquals("Hello, {.", capture.getMessage()); + } + + /** + * Test LogSF.log with missing argument. + */ + public void testLogMissingArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.log(logger, Level.ERROR, "Hello, {}World", new Object[0]); + assertEquals("Hello, {}World", capture.getMessage()); + } + + /** + * Test LogSF.log with single field pattern with string argument. + */ + public void testLogString() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.log(logger, Level.ERROR, "Hello, {}", "World"); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogSF.log with single field pattern with null argument. + */ + public void testLogNull() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.log(logger, Level.ERROR, "Hello, {}", (Object) null); + assertEquals("Hello, null", capture.getMessage()); + } + + /** + * Test LogSF.log with single field pattern with int argument. + */ + public void testLogInt() { + LogCapture capture = new LogCapture(Level.ERROR); + int val = 42; + LogSF.log(logger, Level.ERROR, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.log with single field pattern with byte argument. + */ + public void testLogByte() { + LogCapture capture = new LogCapture(Level.ERROR); + byte val = 42; + LogSF.log(logger, Level.ERROR, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.log with single field pattern with short argument. + */ + public void testLogShort() { + LogCapture capture = new LogCapture(Level.ERROR); + short val = 42; + LogSF.log(logger, Level.ERROR, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.log with single field pattern with long argument. + */ + public void testLogLong() { + LogCapture capture = new LogCapture(Level.ERROR); + long val = 42; + LogSF.log(logger, Level.ERROR, "Iteration {}", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.log with single field pattern with char argument. + */ + public void testLogChar() { + LogCapture capture = new LogCapture(Level.ERROR); + char val = 'C'; + LogSF.log(logger, Level.ERROR, "Iteration {}", val); + assertEquals("Iteration C", capture.getMessage()); + } + + /** + * Test LogSF.log with single field pattern with boolean argument. + */ + public void testLogBoolean() { + LogCapture capture = new LogCapture(Level.ERROR); + boolean val = true; + LogSF.log(logger, Level.ERROR, "Iteration {}", val); + assertEquals("Iteration true", capture.getMessage()); + } + + /** + * Test LogSF.log with single field pattern with float argument. + */ + public void testLogFloat() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.log(logger, Level.ERROR, "Iteration {}", (float) Math.PI); + + String expected = "Iteration " + String.valueOf(new Float(Math.PI)); + assertEquals(expected, capture.getMessage()); + } + + /** + * Test LogSF.log with single field pattern with double argument. + */ + public void testLogDouble() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.log(logger, Level.ERROR, "Iteration {}", Math.PI); + + String expected = "Iteration " + String.valueOf(new Double(Math.PI)); + assertEquals(expected, capture.getMessage()); + } + + /** + * Test LogSF.log with two arguments. + */ + public void testLogTwoArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.log(logger, Level.ERROR, "{}, {}.", "Hello", "World"); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogSF.log with three arguments. + */ + public void testLogThreeArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.log(logger, Level.ERROR, "{}{} {}.", "Hello", ",", "World"); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogSF.log with four arguments. + */ + public void testLogFourArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.log(logger, Level.ERROR, "{}{} {}{}", "Hello", ",", "World", "."); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogSF.log with Object[] argument. + */ + public void testLogArrayArg() { + LogCapture capture = new LogCapture(Level.ERROR); + Object[] args = new Object[] { "Hello", ",", "World", "." }; + LogSF.log(logger, Level.ERROR, "{}{} {}{}", args); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Bundle name for resource bundle tests. + */ + private static final String BUNDLE_NAME = + "org.apache.log4j.TestLogSFPatterns"; + + /** + * Test LogSF.logrb with null bundle name. + */ + public void testLogrbNullBundle() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.logrb(logger, Level.ERROR, null, "Iteration0", Math.PI); + assertEquals("Iteration0", capture.getMessage()); + } + + /** + * Test LogSF.logrb with null key. + */ + public void testLogrbNullKey() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.logrb(logger, Level.ERROR, BUNDLE_NAME, null, Math.PI); + assertNull(capture.getMessage()); + } + + /** + * Test LogSF.logrb with no-field pattern. + */ + public void testLogrbNoArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Hello1", Math.PI); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogSF.logrb with malformed pattern. + */ + public void testLogrbBadPattern() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Malformed", Math.PI); + assertEquals("Hello, {.", capture.getMessage()); + } + + /** + * Test LogSF.logrb with missing argument. + */ + public void testLogrbMissingArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Hello2", new Object[0]); + assertEquals("Hello, {}World", capture.getMessage()); + } + + /** + * Test LogSF.logrb with single field pattern with string argument. + */ + public void testLogrbString() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Hello3", "World"); + assertEquals("Hello, World", capture.getMessage()); + } + + /** + * Test LogSF.logrb with single field pattern with null argument. + */ + public void testLogrbNull() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Hello3", (Object) null); + assertEquals("Hello, null", capture.getMessage()); + } + + /** + * Test LogSF.logrb with single field pattern with int argument. + */ + public void testLogrbInt() { + LogCapture capture = new LogCapture(Level.ERROR); + int val = 42; + LogSF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Iteration0", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.logrb with single field pattern with byte argument. + */ + public void testLogrbByte() { + LogCapture capture = new LogCapture(Level.ERROR); + byte val = 42; + LogSF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Iteration0", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.logrb with single field pattern with short argument. + */ + public void testLogrbShort() { + LogCapture capture = new LogCapture(Level.ERROR); + short val = 42; + LogSF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Iteration0", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.logrb with single field pattern with long argument. + */ + public void testLogrbLong() { + LogCapture capture = new LogCapture(Level.ERROR); + long val = 42; + LogSF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Iteration0", val); + assertEquals("Iteration 42", capture.getMessage()); + } + + /** + * Test LogSF.logrb with single field pattern with char argument. + */ + public void testLogrbChar() { + LogCapture capture = new LogCapture(Level.ERROR); + char val = 'C'; + LogSF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Iteration0", val); + assertEquals("Iteration C", capture.getMessage()); + } + + /** + * Test LogSF.logrb with single field pattern with boolean argument. + */ + public void testLogrbBoolean() { + LogCapture capture = new LogCapture(Level.ERROR); + boolean val = true; + LogSF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Iteration0", val); + assertEquals("Iteration true", capture.getMessage()); + } + + /** + * Test LogSF.logrb with single field pattern with float argument. + */ + public void testLogrbFloat() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.logrb(logger, Level.ERROR, BUNDLE_NAME, + "Iteration0", (float) Math.PI); + + String expected = "Iteration " + String.valueOf(new Float(Math.PI)); + assertEquals(expected, capture.getMessage()); + } + + /** + * Test LogSF.logrb with single field pattern with double argument. + */ + public void testLogrbDouble() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.logrb(logger, Level.ERROR, BUNDLE_NAME, "Iteration0", Math.PI); + + String expected = "Iteration " + String.valueOf(new Double(Math.PI)); + assertEquals(expected, capture.getMessage()); + } + + /** + * Test LogSF.logrb with two arguments. + */ + public void testLogrbTwoArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.logrb(logger, Level.ERROR, + BUNDLE_NAME, "Hello4", "Hello", "World"); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogSF.logrb with three arguments. + */ + public void testLogrbThreeArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.logrb(logger, Level.ERROR, + BUNDLE_NAME, "Hello5", "Hello", ",", "World"); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogSF.logrb with four arguments. + */ + public void testLogrbFourArg() { + LogCapture capture = new LogCapture(Level.ERROR); + LogSF.logrb(logger, Level.ERROR, + BUNDLE_NAME, "Hello6", "Hello", ",", "World", "."); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test LogSF.logrb with Object[] argument. + */ + public void testLogrbArrayArg() { + LogCapture capture = new LogCapture(Level.ERROR); + Object[] args = new Object[] { "Hello", ",", "World", "." }; + LogSF.logrb(logger, Level.ERROR, + BUNDLE_NAME, "Hello6", args); + assertEquals("Hello, World.", capture.getMessage()); + } + + /** + * Test \\{ escape sequence when only one parameter is present. + * + */ + public void testEscapeOneParam() { + LogCapture capture = new LogCapture(Level.INFO); + LogSF.info(logger, "\\{}\\{{}}, World}\\{","Hello"); + assertEquals("{}{Hello}, World}{", capture.getMessage()); + } + + /** + * Test \\{ escape sequence when more than one parameter is present. + * + */ + public void testEscapeTwoParam() { + LogCapture capture = new LogCapture(Level.INFO); + LogSF.info(logger, "\\{}\\{{}}, {}}{}\\{","Hello", "World"); + assertEquals("{}{Hello}, World}{}{", capture.getMessage()); + } +} diff --git a/tests/src/java/org/apache/log4j/TestLogXF.java b/tests/src/java/org/apache/log4j/TestLogXF.java new file mode 100644 index 0000000000..fd12483bef --- /dev/null +++ b/tests/src/java/org/apache/log4j/TestLogXF.java @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j; + +import junit.framework.TestCase; + + +/** + * Unit test for LogXF. + */ +public class TestLogXF extends TestCase { + /** + * Logger. + */ + private final Logger logger = Logger.getLogger( + "org.apache.log4j.formatter.TestLogXF"); + + /** + * Create the test case + * + * @param testName name of the test case + */ + public TestLogXF(String testName) { + super(testName); + } + + + /** + * Post test clean up. + */ + public void tearDown() { + LogManager.resetConfiguration(); + } + + private static class BadStringifier { + private BadStringifier() {} + public static BadStringifier INSTANCE = new BadStringifier(); + public String toString() { + throw new NullPointerException(); + } + } + + + /** + * Test LogXF.entering with null class and method. + */ + public void testEnteringNullNull() { + LogCapture capture = new LogCapture(Level.DEBUG); + logger.setLevel(Level.DEBUG); + LogXF.entering(logger, null, null); + assertEquals("null.null ENTRY", capture.getMessage()); + } + + + /** + * Test LogXF.entering with null class, method and parameter. + */ + public void testEnteringNullNullNull() { + LogCapture capture = new LogCapture(Level.DEBUG); + logger.setLevel(Level.DEBUG); + LogXF.entering(logger, null, null, (String) null); + assertEquals("null.null ENTRY null", capture.getMessage()); + } + + /** + * Test LogXF.entering with null class, method and parameters. + */ + public void testEnteringNullNullNullArray() { + LogCapture capture = new LogCapture(Level.DEBUG); + logger.setLevel(Level.DEBUG); + LogXF.entering(logger, null, null, (Object[]) null); + assertEquals("null.null ENTRY {}", capture.getMessage()); + } + + /** + * Test LogXF.entering with class and method. + */ + public void testEntering() { + LogCapture capture = new LogCapture(Level.DEBUG); + logger.setLevel(Level.DEBUG); + LogXF.entering(logger, "SomeClass", "someMethod"); + assertEquals("SomeClass.someMethod ENTRY", capture.getMessage()); + } + + /** + * Test LogXF.entering with class, method and parameter. + */ + public void testEnteringWithParam() { + LogCapture capture = new LogCapture(Level.DEBUG); + logger.setLevel(Level.DEBUG); + LogXF.entering(logger, "SomeClass", "someMethod", "someParam"); + assertEquals("SomeClass.someMethod ENTRY someParam", capture.getMessage()); + } + + /** + * Test LogXF.entering with class, method and bad parameter. + */ + public void testEnteringWithBadParam() { + LogCapture capture = new LogCapture(Level.DEBUG); + logger.setLevel(Level.DEBUG); + LogXF.entering(logger, "SomeClass", "someMethod", BadStringifier.INSTANCE); + assertEquals("SomeClass.someMethod ENTRY ?", capture.getMessage()); + } + + /** + * Test LogXF.entering with class, method and bad parameters. + */ + public void testEnteringWithBadParams() { + LogCapture capture = new LogCapture(Level.DEBUG); + logger.setLevel(Level.DEBUG); + LogXF.entering(logger, "SomeClass", "someMethod", new Object[]{"param1",BadStringifier.INSTANCE}); + assertEquals("SomeClass.someMethod ENTRY {param1,?}", capture.getMessage()); + } + + + /** + * Test LogXF.exiting with null class and method. + */ + public void testExitingNullNull() { + LogCapture capture = new LogCapture(Level.DEBUG); + logger.setLevel(Level.DEBUG); + LogXF.exiting(logger, null, null); + assertEquals("null.null RETURN", capture.getMessage()); + } + + + /** + * Test LogXF.exiting with null class, method and parameter. + */ + public void testExitingNullNullNull() { + LogCapture capture = new LogCapture(Level.DEBUG); + logger.setLevel(Level.DEBUG); + LogXF.exiting(logger, null, null, (String) null); + assertEquals("null.null RETURN null", capture.getMessage()); + } + + + /** + * Test LogXF.exiting with class and method. + */ + public void testExiting() { + LogCapture capture = new LogCapture(Level.DEBUG); + logger.setLevel(Level.DEBUG); + LogXF.exiting(logger, "SomeClass", "someMethod"); + assertEquals("SomeClass.someMethod RETURN", capture.getMessage()); + } + + /** + * Test LogXF.exiting with class, method and return value. + */ + public void testExitingWithValue() { + LogCapture capture = new LogCapture(Level.DEBUG); + logger.setLevel(Level.DEBUG); + LogXF.exiting(logger, "SomeClass", "someMethod", "someValue"); + assertEquals("SomeClass.someMethod RETURN someValue", capture.getMessage()); + } + + /** + * Test LogXF.exiting with class, method and bad return value. + */ + public void testExitingWithBadValue() { + LogCapture capture = new LogCapture(Level.DEBUG); + logger.setLevel(Level.DEBUG); + LogXF.exiting(logger, "SomeClass", "someMethod", BadStringifier.INSTANCE); + assertEquals("SomeClass.someMethod RETURN ?", capture.getMessage()); + } + + + /** + * Test LogXF.throwing with null class, method and throwable. + */ + public void testThrowingNullNullNull() { + LogCapture capture = new LogCapture(Level.DEBUG); + logger.setLevel(Level.DEBUG); + LogXF.throwing(logger, null, null, null); + assertEquals("null.null THROW", capture.getMessage()); + } + + + /** + * Test LogXF.exiting with class and method. + */ + public void testThrowing() { + LogCapture capture = new LogCapture(Level.DEBUG); + logger.setLevel(Level.DEBUG); + LogXF.throwing(logger, "SomeClass", "someMethod", new IllegalArgumentException()); + assertEquals("SomeClass.someMethod THROW", capture.getMessage()); + } + +} diff --git a/tests/src/java/org/apache/log4j/VectorAppender.java b/tests/src/java/org/apache/log4j/VectorAppender.java index d7833a8b14..4fb0ca2229 100644 --- a/tests/src/java/org/apache/log4j/VectorAppender.java +++ b/tests/src/java/org/apache/log4j/VectorAppender.java @@ -25,15 +25,19 @@ @author Ceki Gülcü */ public class VectorAppender extends AppenderSkeleton { - public Vector vector; - long delay = 0; + public Vector vector; public VectorAppender() { - super(true); vector = new Vector(); } + /** + Does nothing. + */ + public void activateOptions() { + } + /** This method is called by the {@link AppenderSkeleton#doAppend} @@ -41,31 +45,27 @@ public VectorAppender() { */ public void append(LoggingEvent event) { - if(delay > 0) { - try { - Thread.sleep(delay); - } catch (Exception e) { - } + //System.out.println("---Vector appender called with message ["+event.getRenderedMessage()+"]."); + //System.out.flush(); + try { + Thread.sleep(100); + } catch(Exception e) { } - vector.addElement(event); - } + } - /** - * Returns a vector of {@link LoggingEvent}. - */ public Vector getVector() { return vector; } public synchronized void close() { - if (this.closed) { - return; + if(this.closed) { + return; } - this.closed = true; } + public boolean isClosed() { return closed; } @@ -73,19 +73,4 @@ public boolean isClosed() { public boolean requiresLayout() { return false; } - - /** - * Returns a delay to log. - */ - public long getDelay() { - return delay; - } - - /** - * Sets a delay to log. - */ - public void setDelay(long delay) { - this.delay = delay; - } - } diff --git a/tests/src/java/org/apache/log4j/VectorErrorHandler.java b/tests/src/java/org/apache/log4j/VectorErrorHandler.java index 3472951aa0..a08726c2f0 100644 --- a/tests/src/java/org/apache/log4j/VectorErrorHandler.java +++ b/tests/src/java/org/apache/log4j/VectorErrorHandler.java @@ -17,6 +17,7 @@ package org.apache.log4j; +import org.apache.log4j.spi.ErrorHandler; import org.apache.log4j.spi.LoggingEvent; import java.util.Vector; @@ -27,10 +28,8 @@ * by appenders. * * @author Curt Arnold - * @deprecated since ErrorHandler is deprecated */ -public final class VectorErrorHandler - implements org.apache.log4j.spi.ErrorHandler { +public final class VectorErrorHandler implements ErrorHandler { /** * Logger. */ diff --git a/tests/src/java/org/apache/log4j/WriterAppenderTest.java b/tests/src/java/org/apache/log4j/WriterAppenderTest.java deleted file mode 100644 index 9a02ad9469..0000000000 --- a/tests/src/java/org/apache/log4j/WriterAppenderTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j; - -import java.io.CharArrayWriter; - - -/** - * - * Test if WriterAppender honors the Appender contract. - * - * @author Ceki Gülcü - */ -public class WriterAppenderTest extends AbstractAppenderTest { - protected AppenderSkeleton getAppender() { - return new WriterAppender(); - } - - protected AppenderSkeleton getConfiguredAppender() { - WriterAppender wa = new WriterAppender(); - - // set a bogus writer - wa.setWriter(new CharArrayWriter()); - // set a bogus layout - wa.setLayout(new DummyLayout()); - return wa; - } - - public void testPartiallyConfiguredAppender() { - WriterAppender wa1 = new WriterAppender(); - - // set a bogus writer - wa1.setWriter(new CharArrayWriter()); - assertFalse(wa1.isActive()); - - WriterAppender wa2 = new WriterAppender(); - - // set a bogus writer - wa2.setLayout(new DummyLayout()); - assertFalse(wa2.isActive()); - } -} diff --git a/tests/src/java/org/apache/log4j/concurrent/ConcurrentAppenderTest.java b/tests/src/java/org/apache/log4j/concurrent/ConcurrentAppenderTest.java deleted file mode 100644 index 9b9876deef..0000000000 --- a/tests/src/java/org/apache/log4j/concurrent/ConcurrentAppenderTest.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.concurrent; - -import junit.framework.TestCase; -import org.apache.log4j.Logger; -import org.apache.log4j.Level; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.SimpleLayout; -import org.apache.log4j.filter.DenyAllFilter; -import org.apache.log4j.filter.StringMatchFilter; - -/** - * Tests of ConcurrentAppender. - */ -public class ConcurrentAppenderTest extends TestCase { - - private Logger log = Logger.getLogger(ConcurrentAppenderTest.class); - - private MyConcurrentAppender a = new MyConcurrentAppender(); - - private String name = "name"; - - private String msg = "Hello, World"; - - private SimpleLayout layout = new SimpleLayout(); - - private DenyAllFilter denyFilter = new DenyAllFilter(); - - private StringMatchFilter stringMatchFilter = new StringMatchFilter(); - { - stringMatchFilter.setStringToMatch("yo"); - } - - /** - * Tests set and get methods. - */ - public void testSetGet() { - assertEquals(false, a.isActive()); - assertEquals(false, a.isClosed()); - assertEquals(false, a.getClosed()); - assertEquals(null, a.getName()); - a.setName(name); - assertEquals(name, a.getName()); - assertEquals(null, a.getThreshold()); - a.setThreshold(Level.INFO); - assertEquals(Level.INFO, a.getThreshold()); - assertEquals(null, a.getLayout()); - a.setLayout(layout); - assertEquals(layout, a.getLayout()); - - assertNotNull(a.getErrorHandler()); - a.setErrorHandler(null); - assertNotNull(a.toString()); - } - - /** - * Tests log methods, threshold, filter. - */ - public void testLog() { - log.addAppender(a); - log.debug(msg); - assertEquals("not activated", null, a.event); - a.activateOptions(); - log.debug(msg); - assertNotNull(a.event); - - a.setThreshold(Level.INFO); - a.event = null; - log.debug(msg); - assertEquals("filtered", null, a.event); - log.fatal(msg); - assertNotNull(a.event); - - a.event = null; - stringMatchFilter.setStringToMatch("yo"); - a.addFilter(stringMatchFilter); - a.addFilter(denyFilter); - log.fatal("Not y and o"); - assertEquals("filtered", null, a.event); - log.fatal("yo yo yo"); - assertNotNull(a.event); - assertEquals(stringMatchFilter, a.getFilter()); - - a.clearFilters(); - a.event = null; - log.fatal("Not y and o"); - assertNotNull("no longer filtered", a.event); - } - - /** - * Tests active and close methods. - */ - public void testClose() { - log.addAppender(a); - log.debug("not active"); - a.activateOptions(); - assertEquals(true, a.isActive()); - a.close(); - assertEquals(true, a.internalClosed); - assertEquals(true, a.isClosed()); - assertEquals(true, a.getClosed()); - log.debug("not logged"); - assertEquals("closed", null, a.event); - a.close(); // shouldn't call internalClose() twice - assertEquals(true, a.internalClosed); - assertEquals(true, a.isClosed()); - } - - class MyConcurrentAppender extends ConcurrentAppender { - - LoggingEvent event; - - boolean internalClosed; - - MyConcurrentAppender() { - super(false); - } - - protected void append(LoggingEvent event) { - this.event = event; - } - - public boolean requiresLayout() { - return true; - } - - protected void internalClose() { - if (internalClosed) - throw new IllegalStateException(); - internalClosed = true; - } - - } - -} diff --git a/tests/src/java/org/apache/log4j/concurrent/ConsoleAppenderTest.java b/tests/src/java/org/apache/log4j/concurrent/ConsoleAppenderTest.java deleted file mode 100644 index bd9c77953f..0000000000 --- a/tests/src/java/org/apache/log4j/concurrent/ConsoleAppenderTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.concurrent; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; - -import junit.framework.TestCase; - -import org.apache.log4j.Logger; -import org.apache.log4j.SimpleLayout; - -/** - * Tests of ConsoleAppender. - */ -public class ConsoleAppenderTest extends TestCase { - - private Logger log = Logger.getLogger(ConsoleAppender.class); - - private ConsoleAppender appender = new ConsoleAppender(); - - private SimpleLayout layout = new SimpleLayout(); - - private ByteArrayOutputStream bo1 = new ByteArrayOutputStream(); - - private ByteArrayOutputStream bo2 = new ByteArrayOutputStream(); - - private PrintStream err = new PrintStream(bo1); - - private PrintStream out = new PrintStream(bo2); - { - appender.setLayout(layout); - log.addAppender(appender); - } - - /** - * Tests ConsoleAppender get set and toString. - */ - public void testBasic() { - assertEquals(false, appender.isActive()); - System.setErr(err); - appender.setTarget("System.err"); - assertEquals(false, appender.isActive()); - appender.activateOptions(); - assertEquals(true, appender.isActive()); - log.debug("HI"); - assertEquals("DEBUG - HI", bo1.toString().trim()); - assertEquals("", bo2.toString()); - - appender.setTarget("System.out"); - appender.activateOptions(); - System.setOut(out); - log.debug("HI"); - assertEquals("not following", "", bo2.toString().trim()); - - appender.setFollow(true); - appender.activateOptions(); - log.debug("HI"); - assertEquals("DEBUG - HI", bo2.toString().trim()); - } - -} diff --git a/tests/src/java/org/apache/log4j/concurrent/FileAppenderTest.java b/tests/src/java/org/apache/log4j/concurrent/FileAppenderTest.java deleted file mode 100644 index 317906c085..0000000000 --- a/tests/src/java/org/apache/log4j/concurrent/FileAppenderTest.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - /* - * Copyright 2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.concurrent; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; - -import junit.framework.TestCase; - -import org.apache.log4j.Logger; -import org.apache.log4j.SimpleLayout; - -/** - * Tests of FileAppender. - */ -public class FileAppenderTest extends TestCase { - - private Logger log = Logger.getLogger(FileAppender.class); - - private FileAppender appender = new FileAppender(); - - private SimpleLayout layout = new SimpleLayout(); - - private File f1; - - protected void setUp() throws Exception { - f1 = File.createTempFile("FileAppenderTest", ".tmp"); - f1.deleteOnExit(); - appender.setLayout(layout); - appender.activateOptions(); // won't work - appender.setFile(f1.toString()); - log.addAppender(appender); - } - - /** - * Tests FileAppender methods and writing. - */ - public void testBasic() throws Exception { - assertEquals(false, appender.isActive()); - assertEquals(true, appender.getAppend()); - assertEquals(f1.toString(), appender.getFile()); - - // Check and change default options - assertEquals(true, appender.getBufferedIO()); - appender.setBufferedIO(false); - assertEquals(false, appender.getBufferedIO()); - assertEquals(true, appender.getAppend()); - appender.setAppend(false); - assertEquals(false, appender.getAppend()); - appender.setBufferSize(400); - assertEquals(400, appender.getBufferSize()); - appender.activateOptions(); // works - - log.debug("HI"); - appender.close(); - readHI(); - } - - private void readHI() throws Exception { - BufferedReader r = new BufferedReader(new FileReader(f1)); - assertEquals("DEBUG - HI", r.readLine()); - r.close(); - } - - /** - * Tests that FileAppender works with default options. - */ - public void testDefaultOptions() throws Exception { - appender.activateOptions(); - log.debug("HI"); - appender.close(); - readHI(); - } - -} diff --git a/tests/src/java/org/apache/log4j/concurrent/RollingFileAppenderTest.java b/tests/src/java/org/apache/log4j/concurrent/RollingFileAppenderTest.java deleted file mode 100644 index 5fb0b5e214..0000000000 --- a/tests/src/java/org/apache/log4j/concurrent/RollingFileAppenderTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.concurrent; - -import java.io.File; - -import junit.framework.TestCase; - -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.PatternLayout; -import org.apache.log4j.rolling.FixedWindowRollingPolicy; -import org.apache.log4j.rolling.SizeBasedTriggeringPolicy; -import org.apache.log4j.util.Compare; - -/** - * Tests RollingFileAppender in the concurrent library. Taken from - * SizeBasedRollingTest. Not a complete functionality test. - */ -public class RollingFileAppenderTest extends TestCase { - Logger logger = Logger.getLogger(RollingFileAppenderTest.class); - - public RollingFileAppenderTest(String name) { - super(name); - } - - public void setUp() { - } - - public void tearDown() { - LogManager.shutdown(); - } - - /** - * Test basic rolling functionality with explicit setting of - * FileAppender.file. - */ - public void test2() throws Exception { - PatternLayout layout = new PatternLayout("%m\n"); - RollingFileAppender rfa = new RollingFileAppender(); - rfa.setName("ROLLING"); - rfa.setAppend(false); - rfa.setLayout(layout); - rfa.setFile("output/sizeBased-test2.log"); - - FixedWindowRollingPolicy swrp = new FixedWindowRollingPolicy(); - SizeBasedTriggeringPolicy sbtp = new SizeBasedTriggeringPolicy(); - - sbtp.setMaxFileSize(100); - swrp.setMinIndex(0); - - swrp.setFileNamePattern("output/sizeBased-test2.%i"); - swrp.activateOptions(); - - rfa.setRollingPolicy(swrp); - rfa.setTriggeringPolicy(sbtp); - rfa.activateOptions(); - logger.addAppender(rfa); - - // Write exactly 10 bytes with each log - for (int i = 0; i < 25; i++) { - if (i < 10) { - logger.debug("Hello---" + i); - } else if (i < 100) { - logger.debug("Hello--" + i); - } - } - - assertTrue(new File("output/sizeBased-test2.log").exists()); - assertTrue(new File("output/sizeBased-test2.0").exists()); - assertTrue(new File("output/sizeBased-test2.1").exists()); - - assertTrue(Compare.compare("output/sizeBased-test2.log", - "witness/rolling/sbr-test2.log")); - assertTrue(Compare.compare("output/sizeBased-test2.0", - "witness/rolling/sbr-test2.0")); - assertTrue(Compare.compare("output/sizeBased-test2.1", - "witness/rolling/sbr-test2.1")); - } - -} diff --git a/tests/src/java/org/apache/log4j/concurrent/SynchronizedBooleanTest.java b/tests/src/java/org/apache/log4j/concurrent/SynchronizedBooleanTest.java deleted file mode 100644 index 48d7d9f0a2..0000000000 --- a/tests/src/java/org/apache/log4j/concurrent/SynchronizedBooleanTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.concurrent; - -import junit.framework.TestCase; - -/** - * Tests of SynchronizedBoolean. - */ -public class SynchronizedBooleanTest extends TestCase { - - /** - * Tests SynchronizedBoolean get set and toString. - */ - public void testBasic() { - SynchronizedBoolean sb = new SynchronizedBoolean(true); - assertEquals(true, sb.get()); - sb.set(false); - assertEquals(false, sb.get()); - assertEquals("false", sb.toString()); - } - -} diff --git a/tests/src/java/org/apache/log4j/concurrent/WriterAppenderTest.java b/tests/src/java/org/apache/log4j/concurrent/WriterAppenderTest.java deleted file mode 100644 index 7b4262543e..0000000000 --- a/tests/src/java/org/apache/log4j/concurrent/WriterAppenderTest.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.concurrent; - -import java.io.Writer; -import java.io.IOException; -import junit.framework.TestCase; -import org.apache.log4j.Layout; -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.apache.log4j.SimpleLayout; - -/** - * Tests of WriterAppender. - */ -public class WriterAppenderTest extends TestCase { - - private Logger log = Logger.getLogger(ConcurrentAppenderTest.class); - - private WriterAppender appender = new WriterAppender(); - - private SimpleLayout layout = new SimpleLayout(); - - { - log.addAppender(appender); - layout.setFooter("F"); - layout.setHeader("H"); - } - - private MyStringWriter sw = new MyStringWriter(); - - private static class MyStringWriter extends Writer { - public boolean closed = false; - - public boolean flushed = false; - - public boolean toss = false; - - StringBuffer sb = new StringBuffer(); - - public void write(char[] cbuf, int off, int len) throws IOException { - sb.append(cbuf, off, len); - if (toss) - throw new IOException(); - } - - public void flush() { - flushed = true; - } - - public void close() throws IOException { - closed = true; - } - - public String toString() { - return sb.toString(); - } - - } - - /** - * Tests WriterAppender get set and toString. - */ - public void testBasic() { - assertEquals(true, appender.getImmediateFlush()); - appender.setImmediateFlush(false); - assertEquals(false, appender.getImmediateFlush()); - appender.activateOptions(); - assertEquals(false, appender.isActive()); - appender.setLayout(layout); - appender.activateOptions(); - assertEquals(false, appender.isActive()); - appender.setWriter(sw); - appender.activateOptions(); - assertEquals(true, appender.isActive()); - appender.close(); - assertEquals(true, sw.closed); - assertEquals(true, sw.flushed); - assertEquals(true, appender.requiresLayout()); - appender.setEncoding("ASCII"); - assertEquals("ASCII", appender.getEncoding()); - } - - /** - * Tests WriterAppender output. - */ - public void testOutput() { - appender.setLayout(layout); - appender.setWriter(sw); - appender.activateOptions(); - log.debug("HI"); - assertEquals(true, sw.flushed); - assertEquals("HDEBUG - HI", sw.toString().trim()); - appender.close(); - log.debug("HI"); - assertEquals("HDEBUG - HI" + Layout.LINE_SEP + "F", sw.toString().trim()); - } - - /** - * Tests Throwable output. - */ - public void testThrowable() { - appender.setLayout(layout); - appender.setWriter(sw); - appender.activateOptions(); - appender.setImmediateFlush(false); - sw.flushed = false; - log.debug("HI", new Throwable()); - assertEquals(false, sw.flushed); - String s = sw.toString(); - assertTrue(":" + s, s.startsWith("HDEBUG - HI")); - assertTrue("has a stack trace", s.length() > 40); - - appender.setImmediateFlush(true); - assertEquals(true, appender.isActive()); - sw.toss = true; - log.debug("HI"); - log.debug("HI"); - assertEquals(false, appender.isActive()); - } - -} diff --git a/tests/src/java/org/apache/log4j/config/PropertySetterTest.java b/tests/src/java/org/apache/log4j/config/PropertySetterTest.java deleted file mode 100644 index 26bc5eaab8..0000000000 --- a/tests/src/java/org/apache/log4j/config/PropertySetterTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.apache.log4j.config; - -import java.util.Date; - -import junit.framework.TestCase; - -public class PropertySetterTest extends TestCase { - - public void testSetter() { - /* - Properties p = new Properties(); - p.put("log4j.debug", "true"); - p.put("log4j.appender.A", ""); - p.put("log4j.rootLogger", "DEBUG,A"); - PropertyConfigurator.configure(p); - */ - - Date d = new Date(); - PropertySetter ps = new PropertySetter(d); - ps.setProperty("time", "0"); - assertEquals(0L, d.getTime()); - - // no properties to set, warn - PropertySetter ps2 = new PropertySetter(new Object()); - ps2.setProperty("class", "abc"); - } - -} diff --git a/tests/src/java/org/apache/log4j/customLogger/XLogger.java b/tests/src/java/org/apache/log4j/customLogger/XLogger.java index aa6025ca6b..ad327dbe09 100644 --- a/tests/src/java/org/apache/log4j/customLogger/XLogger.java +++ b/tests/src/java/org/apache/log4j/customLogger/XLogger.java @@ -17,12 +17,12 @@ package org.apache.log4j.customLogger; + import org.apache.log4j.*; -import org.apache.log4j.spi.LoggerFactory; import org.apache.log4j.spi.OptionHandler; +import org.apache.log4j.spi.LoggerFactory; import org.apache.log4j.xml.XLevel; - /** A simple example showing Logger sub-classing. It shows the minimum steps necessary to implement one's {@link LoggerFactory}. @@ -30,6 +30,7 @@ belong to different classes. */ public class XLogger extends Logger implements OptionHandler { + // It's usually a good idea to add a dot suffix to the fully // qualified class name. This makes caller localization to work // properly even from classes that have almost the same fully @@ -38,6 +39,7 @@ public class XLogger extends Logger implements OptionHandler { // It's enough to instantiate a factory once and for all. private static XFactory factory = new XFactory(); + String suffix = ""; /** @@ -47,96 +49,111 @@ protected XLogger(String name) { super(name); } - /** + /** Nothing to activate. */ - public void activateOptions() { + public + void activateOptions() { } /** Overrides the standard debug method by appending the value of - suffix variable to each message. + suffix variable to each message. */ - public void debug(String message) { + public + void debug(String message) { super.log(FQCN, Level.DEBUG, message + " " + suffix, null); } /** We introduce a new printing method in order to support {@link XLevel#LETHAL}. */ - public void lethal(String message, Throwable t) { - if (repository.isDisabled(XLevel.LETHAL_INT)) { - return; + public + void lethal(String message, Throwable t) { + if(repository.isDisabled(XLevel.LETHAL_INT)) { + return; } - - if (XLevel.LETHAL.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, XLevel.LETHAL, message, t); + if(XLevel.LETHAL.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, XLevel.LETHAL, message, t); } } /** We introduce a new printing method in order to support {@link XLevel#LETHAL}. */ - public void lethal(String message) { - if (repository.isDisabled(XLevel.LETHAL_INT)) { - return; + public + void lethal(String message) { + if(repository.isDisabled(XLevel.LETHAL_INT)) { + return; } - - if (XLevel.LETHAL.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, XLevel.LETHAL, message, null); + if(XLevel.LETHAL.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, XLevel.LETHAL, message, null); } } - public static Logger getLogger(String name) { + static + public + Logger getLogger(String name) { return LogManager.getLogger(name, factory); } - public static Logger getLogger(Class clazz) { + static + public + Logger getLogger(Class clazz) { return XLogger.getLogger(clazz.getName()); } - public String getSuffix() { + + public + String getSuffix() { return suffix; } - public void setSuffix(String suffix) { + public + void setSuffix(String suffix) { this.suffix = suffix; } /** We introduce a new printing method that takes the TRACE level. */ - public void trace(String message, Throwable t) { - if (repository.isDisabled(XLevel.TRACE_INT)) { - return; - } - - if (XLevel.TRACE.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, XLevel.TRACE, message, t); + public + void trace(String message, Throwable t) { + if(repository.isDisabled(XLevel.TRACE_INT)) { + return; + } + if(XLevel.TRACE.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, XLevel.TRACE, message, t); } } /** We introduce a new printing method that takes the TRACE level. */ - public void trace(String message) { - if (repository.isDisabled(XLevel.TRACE_INT)) { - return; - } - - if (XLevel.TRACE.isGreaterOrEqual(this.getEffectiveLevel())) { - forcedLog(FQCN, XLevel.TRACE, message, null); + public + void trace(String message) { + if(repository.isDisabled(XLevel.TRACE_INT)) { + return; + } + if(XLevel.TRACE.isGreaterOrEqual(this.getEffectiveLevel())) { + forcedLog(FQCN, XLevel.TRACE, message, null); } } + + // Any sub-class of Logger must also have its own implementation of // CategoryFactory. public static class XFactory implements LoggerFactory { + public XFactory() { } - public Logger makeNewLoggerInstance(String name) { + public + Logger makeNewLoggerInstance(String name) { return new XLogger(name); } } } + + diff --git a/tests/src/java/org/apache/log4j/customLogger/XLoggerTestCase.java b/tests/src/java/org/apache/log4j/customLogger/XLoggerTestCase.java index 343dbfc213..ac05b765ca 100644 --- a/tests/src/java/org/apache/log4j/customLogger/XLoggerTestCase.java +++ b/tests/src/java/org/apache/log4j/customLogger/XLoggerTestCase.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,25 +17,24 @@ package org.apache.log4j.customLogger; -import junit.framework.Test; +import org.apache.log4j.xml.DOMConfigurator; +import org.apache.log4j.util.*; + import junit.framework.TestCase; import junit.framework.TestSuite; - -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.joran.JoranConfigurator; -import org.apache.log4j.util.*; +import junit.framework.Test; /** Tests handling of custom loggers. - + @author Ceki Gülcü */ public class XLoggerTestCase extends TestCase { + static String FILTERED = "output/filtered"; static XLogger logger = (XLogger) XLogger.getLogger(XLoggerTestCase.class); - public XLoggerTestCase(String name) { + public XLoggerTestCase(String name){ super(name); } @@ -43,27 +42,19 @@ public void tearDown() { logger.getLoggerRepository().resetConfiguration(); } - public void test1() throws Exception { - common(1); - } - - public void test2() throws Exception { - common(2); - } + public void test1() throws Exception { common(1); } + public void test2() throws Exception { common(2); } void common(int number) throws Exception { - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure("input/xml/customLogger" + number + ".xml", LogManager.getLoggerRepository()); + DOMConfigurator.configure("input/xml/customLogger"+number+".xml"); int i = -1; - Logger root = Logger.getRootLogger(); logger.trace("Message " + ++i); logger.debug("Message " + ++i); - logger.warn("Message " + ++i); + logger.warn ("Message " + ++i); logger.error("Message " + ++i); logger.fatal("Message " + ++i); - Exception e = new Exception("Just testing"); logger.debug("Message " + ++i, e); @@ -73,7 +64,8 @@ void common(int number) throws Exception { new LineNumberFilter(), new SunReflectFilter(), new JunitTestRunnerFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/xml/customLogger." + number)); + assertTrue(Compare.compare(FILTERED, "witness/customLogger."+number)); + } public static Test suite() { diff --git a/tests/src/java/org/apache/log4j/db/BindDataSourceToJNDIAction.java b/tests/src/java/org/apache/log4j/db/BindDataSourceToJNDIAction.java deleted file mode 100644 index 11d485a254..0000000000 --- a/tests/src/java/org/apache/log4j/db/BindDataSourceToJNDIAction.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.db; - - -import org.apache.log4j.Logger; -import org.apache.log4j.config.PropertySetter; -import org.apache.log4j.helpers.Option; -import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.joran.action.Action; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.spi.ErrorItem; - -import org.xml.sax.Attributes; - -import javax.naming.Context; -import javax.naming.InitialContext; - -import javax.sql.DataSource; - -/** - * This Joran action is specifically designed for @{link FullCycleDBTest} when - * run in conjunction with a JNDIDataSource. It is used to bind the DataSource - * to JNDI before the FullCycleDBTest executes. - * - * @author Ceki Gulcu - * - */ -public class BindDataSourceToJNDIAction extends Action { - static final Logger logger = - Logger.getLogger(BindDataSourceToJNDIAction.class); - static final String DATA_SOURCE_CLASS = "dataSourceClass"; - static final String URL = "url"; - static final String USER = "user"; - static final String PASSWORD = "password"; - - /** - * Instantiates an a data source and bind it to JNDI - * Most of the required parameters are placed in the ec.substitutionProperties - */ - public void begin( - ExecutionContext ec, String localName, Attributes attributes) { - String dsClassName = ec.getSubstitutionProperty(DATA_SOURCE_CLASS); - - if (Option.isEmpty(dsClassName)) { - getLogger().warn("dsClassName is a required parameter"); - ec.addError(new ErrorItem("dsClassName is a required parameter")); - - return; - } - - String urlStr = ec.getSubstitutionProperty(URL); - String userStr = ec.getSubstitutionProperty(USER); - String passwordStr = ec.getSubstitutionProperty(PASSWORD); - - try { - DataSource ds = - (DataSource) OptionConverter.instantiateByClassName(dsClassName, DataSource.class, null); - - PropertySetter setter = new PropertySetter(ds); - - if (!Option.isEmpty(urlStr)) { - setter.setProperty("url", urlStr); - } - - if (!Option.isEmpty(userStr)) { - setter.setProperty("user", userStr); - } - - if (!Option.isEmpty(passwordStr)) { - setter.setProperty("password", passwordStr); - } - - Context ctx = new InitialContext(); - ctx.rebind("dataSource", ds); - } catch (Exception e) { - logger.error("Could not bind datasource", e); - ec.addError( - new ErrorItem( - "Could not not bind datasource of type [" + dsClassName + "]")); - } - } - - public void end(ExecutionContext ec, String name) { - } - - public void finish(ExecutionContext ec) { - } -} diff --git a/tests/src/java/org/apache/log4j/db/DBPerfTest.java b/tests/src/java/org/apache/log4j/db/DBPerfTest.java deleted file mode 100644 index b3b7dc7c42..0000000000 --- a/tests/src/java/org/apache/log4j/db/DBPerfTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Created on May 21, 2004 - * - * To change the template for this generated file go to - * Window>Preferences>Java>Code Generation>Code and Comments - */ -package org.apache.log4j.db; - -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.MDC; -import org.apache.log4j.joran.JoranConfigurator; - -import junit.framework.TestCase; - -/** - * @author ceki - * - * To change the template for this generated type comment go to - * Window>Preferences>Java>Code Generation>Code and Comments - */ -public class DBPerfTest extends TestCase { - final static Logger logger = Logger.getLogger(DBPerfTest.class); - - String appendConfigFile; - - public DBPerfTest(String arg0) { - super(arg0); - } - - - protected void setUp() throws Exception { - //appendConfigFile = System.getProperty("appendConfigFile"); - //assertNotNull("[appendConfigFile] property must be set for this test", appendConfigFile); - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - - public void testLoop() { - //appendConfigFile = "./input/db/append-with-drivermanager1.xml"; - appendConfigFile = "./input/db/append-with-pooled-datasource1.xml"; - //appendConfigFile = "./input/db/append-with-c3p0.xml"; - - - JoranConfigurator jc1 = new JoranConfigurator(); - jc1.doConfigure(appendConfigFile, LogManager.getLoggerRepository()); - - long startTime = System.currentTimeMillis(); - MDC.put("key1", "vaelu1"); - int i; - for(i = 0; i < 100; i++) { - logger.debug("message "+i); - } - long endTime = System.currentTimeMillis(); - System.out.println("writing "+i+" events took "+(endTime-startTime)+" millis."); - System.out.println("or "+(double)(endTime-startTime)/i+" millis per event."); - } -} diff --git a/tests/src/java/org/apache/log4j/db/FullCycleDBTest.java b/tests/src/java/org/apache/log4j/db/FullCycleDBTest.java deleted file mode 100644 index fb7909e32e..0000000000 --- a/tests/src/java/org/apache/log4j/db/FullCycleDBTest.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.db; - -import java.util.Iterator; -import java.util.Map; -import java.util.Vector; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.apache.log4j.Hierarchy; -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.apache.log4j.MDC; -import org.apache.log4j.VectorAppender; -import org.apache.log4j.helpers.Constants; -import org.apache.log4j.joran.JoranConfigurator; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.RootLogger; -import org.apache.log4j.spi.LocationInfo; - - -/** - * This test case writes a few events into a databases and reads them - * back comparing the event written and read back. - * - *

    It relies heavily on the proper configuration of its environment - * in joran config files as well system properties. - *

    - * - *

    See also the Ant build file in the tests/ directory.

    - * - * @author Ceki Gülcü - */ -public class FullCycleDBTest - extends TestCase { - - Vector witnessEvents; - Hierarchy lrWrite; - Hierarchy lrRead; - String appendConfigFile = null; - String readConfigFile = null; - - - /* - * @see TestCase#setUp() - */ - protected void setUp() - throws Exception { - super.setUp(); - appendConfigFile = System.getProperty("appendConfigFile"); - assertNotNull("[appendConfigFile] property must be set for this test", appendConfigFile); - readConfigFile = System.getProperty("readConfigFile"); - assertNotNull("[readConfigFile] property must be set for this test", readConfigFile); - - witnessEvents = new Vector(); - lrWrite = new Hierarchy(new RootLogger(Level.DEBUG)); - lrWrite.setName("lrWrite"); - lrRead = new Hierarchy(new RootLogger(Level.DEBUG)); - lrRead.setName("lrRead"); - } - - - /* - * @see TestCase#tearDown() - */ - protected void tearDown() - throws Exception { - super.tearDown(); - lrRead.shutdown(); - witnessEvents = null; - } - - /** - * Constructor for DBReeceiverTest. - * @param arg0 - */ - public FullCycleDBTest(String arg0) { - super(arg0); - } - - - /** - * This test starts by writing a single event to a DB using DBAppender - * and then reads it back using DBReceiver. - * - * DB related information is specified within the configuration files. - * @throws Exception - */ - public void testSingleOutput() - throws Exception { - JoranConfigurator jc1 = new JoranConfigurator(); - jc1.doConfigure(appendConfigFile, lrWrite); - - long startTime = System.currentTimeMillis(); - System.out.println("***startTime is "+startTime); - - // Write out just one log message - Logger out = lrWrite.getLogger("testSingleOutput.out"); - out.debug("some message"+startTime); - - VectorAppender witnessAppender = (VectorAppender) lrWrite.getRootLogger().getAppender("VECTOR"); - witnessEvents = witnessAppender.getVector(); - assertEquals(1, witnessEvents.size()); - - // We have to close all appenders before starting to read - lrWrite.shutdown(); - - // now read it back - readBack(readConfigFile, startTime); - - } - - /** - * This test starts by writing a single event to a DB using DBAppender - * and then reads it back using DBReceiver. - * - * The written event includes MDC and repository properties as well as - * exception info. - * - * DB related information is specified within the configuration files. - * @throws Exception - */ - public void testAllFields() { - JoranConfigurator jc1 = new JoranConfigurator(); - jc1.doConfigure(appendConfigFile, lrWrite); - - long startTime = System.currentTimeMillis(); - - // Write out just one log message - lrWrite.setProperty("key1", "value1-"+startTime); - MDC.put("key2", "value2-"+startTime); - Map mdcMap = MDC.getContext(); -// LogLog.info("**********"+mdcMap.size()); - - // Write out just one log message - Logger out = lrWrite.getLogger("out"+startTime); - long sn = LoggingEvent.getSequenceCount(); - - out.debug("some message"+startTime); - MDC.put("key3", "value2-"+startTime); - out.error("some error message"+startTime, new Exception("testing")); - - // we clear the MDC to avoid interference with the events read back from - // the db - MDC.clear(); - - VectorAppender witnessAppender = (VectorAppender) lrWrite.getRootLogger().getAppender("VECTOR"); - witnessEvents = witnessAppender.getVector(); - assertEquals(2, witnessEvents.size()); - - // We have to close all appenders just before starting to read - lrWrite.shutdown(); - - readBack(readConfigFile, startTime); - } - - - void readBack(String configfile, long startTime) { - JoranConfigurator jc2 = new JoranConfigurator(); - jc2.doConfigure(configfile, lrRead); - - // wait a little to allow events to be read - try { Thread.sleep(3100); } catch(Exception e) {} - VectorAppender va = (VectorAppender) lrRead.getRootLogger().getAppender("VECTOR"); - Vector returnedEvents = getRelevantEventsFromVA(va, startTime); - - compareEvents(witnessEvents, returnedEvents); - - } - - void compareEvents(Vector l, Vector r) { - assertNotNull("left vector of events should not be null"); - assertEquals(l.size(), r.size()); - - for(int i = 0; i < r.size(); i++) { - LoggingEvent le = (LoggingEvent) l.get(i); - LoggingEvent re = (LoggingEvent) r.get(i); - assertEquals(le.getMessage(), re.getMessage()); - assertEquals(le.getSequenceNumber(), re.getSequenceNumber()); - assertEquals(le.getLoggerName(), re.getLoggerName()); - assertEquals(le.getLevel(), re.getLevel()); - assertEquals(le.getThreadName(), re.getThreadName()); - if(re.getTimeStamp() < le.getTimeStamp()) { - fail("Returned event cannot preceed witness timestamp"); - } - - if((re.getProperties() != null) && re.getProperties().containsKey(Constants.LOG4J_ID_KEY)) { - re.getProperties().remove(Constants.LOG4J_ID_KEY); - } - - if(le.getProperties() == null || le.getProperties().size() == 0) { - if(!(re.getProperties() == null || re.getProperties().size() == 0)) { - System.out.println("properties are "+re.getProperties()); - fail("Returned event should have been empty"); - } - } else { - assertEquals(le.getProperties(), re.getProperties()); - } - comprareStringArrays( le.getThrowableStrRep(), re.getThrowableStrRep()); - compareLocationInfo(le, re); - } - } - - void comprareStringArrays(String[] la, String[] ra) { - if((la == null) && (ra == null)) { - return; - } - assertEquals(la.length, ra.length); - for(int i = 0; i < la.length; i++) { - assertEquals(la[i], ra[i]); - } - } - - void compareLocationInfo(LoggingEvent l, LoggingEvent r) { - if(l.locationInformationExists()) { - assertEquals(l.getLocationInformation(), r.getLocationInformation()); - } else { - assertEquals(LocationInfo.NA_LOCATION_INFO, r.getLocationInformation()); - } - } - - Vector getRelevantEventsFromVA(VectorAppender va, long startTime) { - assertNotNull(va); - Vector v = va.getVector(); - Vector r = new Vector(); - // remove all elements older than startTime - for(Iterator i = v.iterator(); i.hasNext(); ) { - LoggingEvent event = (LoggingEvent) i.next(); - if(startTime > event.getTimeStamp()) { - System.out.println("***Removing event with timestamp "+event.getTimeStamp()); - } else { - System.out.println("***Keeping event with timestamo"+event.getTimeStamp()); - r.add(event); - } - } - return r; - } - - void dump(Vector v) { - for(int i = 0; i < v.size(); i++) { - LoggingEvent le = (LoggingEvent) v.get(i); - System.out.println("---"+le.getLevel()+" "+le.getLoggerName()+" "+le.getMessage()); - } - } - - public static Test XXsuite() { - TestSuite suite = new TestSuite(); - suite.addTest(new FullCycleDBTest("testSingleOutput")); - suite.addTest(new FullCycleDBTest("testAllFields")); - return suite; - } -} diff --git a/tests/src/java/org/apache/log4j/defaultInit/TestCase1.java b/tests/src/java/org/apache/log4j/defaultInit/TestCase1.java index 01facc7f5a..9a6549fbc5 100644 --- a/tests/src/java/org/apache/log4j/defaultInit/TestCase1.java +++ b/tests/src/java/org/apache/log4j/defaultInit/TestCase1.java @@ -17,14 +17,14 @@ package org.apache.log4j.defaultInit; -import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; - -import org.apache.log4j.*; - +import junit.framework.Test; +import org.apache.log4j.Logger; +import org.apache.log4j.LogManager; public class TestCase1 extends TestCase { + public TestCase1(String name) { super(name); } @@ -45,7 +45,8 @@ public void noneTest() { public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(new TestCase1("noneTest")); - return suite; } + } + diff --git a/tests/src/java/org/apache/log4j/defaultInit/TestCase2.java b/tests/src/java/org/apache/log4j/defaultInit/TestCase2.java index a90d3c7aec..c5552b8117 100644 --- a/tests/src/java/org/apache/log4j/defaultInit/TestCase2.java +++ b/tests/src/java/org/apache/log4j/defaultInit/TestCase2.java @@ -17,16 +17,16 @@ package org.apache.log4j.defaultInit; -import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; - -import org.apache.log4j.*; - +import junit.framework.Test; import java.util.Enumeration; - +import org.apache.log4j.Appender; +import org.apache.log4j.Logger; +import org.apache.log4j.LogManager; public class TestCase2 extends TestCase { + public TestCase2(String name) { super(name); } @@ -42,7 +42,6 @@ public void xmlTest() { Logger root = Logger.getRootLogger(); boolean rootIsConfigured = root.getAllAppenders().hasMoreElements(); assertTrue(rootIsConfigured); - Enumeration e = root.getAllAppenders(); Appender appender = (Appender) e.nextElement(); assertEquals(appender.getName(), "D1"); @@ -51,7 +50,8 @@ public void xmlTest() { public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(new TestCase2("xmlTest")); - return suite; } + } + diff --git a/tests/src/java/org/apache/log4j/defaultInit/TestCase3.java b/tests/src/java/org/apache/log4j/defaultInit/TestCase3.java index 4457158ea3..661a02633a 100644 --- a/tests/src/java/org/apache/log4j/defaultInit/TestCase3.java +++ b/tests/src/java/org/apache/log4j/defaultInit/TestCase3.java @@ -18,10 +18,12 @@ package org.apache.log4j.defaultInit; import junit.framework.TestCase; - +import junit.framework.TestSuite; +import junit.framework.Test; import java.util.Enumeration; - -import org.apache.log4j.*; +import org.apache.log4j.Appender; +import org.apache.log4j.Logger; +import org.apache.log4j.LogManager; public class TestCase3 extends TestCase { @@ -36,7 +38,7 @@ public void tearDown() { LogManager.shutdown(); } - public void testProperties() { + public void propertiesTest() { Logger root = Logger.getRootLogger(); boolean rootIsConfigured = root.getAllAppenders().hasMoreElements(); assertTrue(rootIsConfigured); @@ -45,11 +47,11 @@ public void testProperties() { assertEquals(appender.getName(), "D3"); } -/** public static Test suite() { + public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(new TestCase3("propertiesTest")); return suite; } -**/ + } diff --git a/tests/src/java/org/apache/log4j/defaultInit/TestCase4.java b/tests/src/java/org/apache/log4j/defaultInit/TestCase4.java index 744fef519a..aeed8a13ca 100644 --- a/tests/src/java/org/apache/log4j/defaultInit/TestCase4.java +++ b/tests/src/java/org/apache/log4j/defaultInit/TestCase4.java @@ -17,16 +17,16 @@ package org.apache.log4j.defaultInit; -import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; - -import org.apache.log4j.*; - +import junit.framework.Test; import java.util.Enumeration; - +import org.apache.log4j.Appender; +import org.apache.log4j.Logger; +import org.apache.log4j.LogManager; public class TestCase4 extends TestCase { + public TestCase4(String name) { super(name); } @@ -42,7 +42,6 @@ public void combinedTest() { Logger root = Logger.getRootLogger(); boolean rootIsConfigured = root.getAllAppenders().hasMoreElements(); assertTrue(rootIsConfigured); - Enumeration e = root.getAllAppenders(); Appender appender = (Appender) e.nextElement(); assertEquals(appender.getName(), "D1"); @@ -52,7 +51,8 @@ public void combinedTest() { public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(new TestCase4("combinedTest")); - return suite; } + } + diff --git a/tests/src/java/org/apache/log4j/filter/SimpleFilterTest.java b/tests/src/java/org/apache/log4j/filter/SimpleFilterTest.java deleted file mode 100644 index f270e09130..0000000000 --- a/tests/src/java/org/apache/log4j/filter/SimpleFilterTest.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.filter; - -import org.apache.log4j.Level; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.joran.JoranConfigurator; -import org.apache.log4j.util.Compare; -import org.apache.log4j.util.ControlFilter; -import org.apache.log4j.util.Filter; -import org.apache.log4j.util.JunitTestRunnerFilter; -import org.apache.log4j.util.LineNumberFilter; -import org.apache.log4j.util.SunReflectFilter; -import org.apache.log4j.util.Transformer; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - - -/** - * Various tests verifying that filters work properly and that - * JoranConfigurator can effectively parse config files containing them. - * - * @author Ceki Gulcu - * - */ -public class SimpleFilterTest extends TestCase { - Logger root; - Logger logger; - - public final static String FILTERED = "output/filtered"; - public final static String TEMP = "output/temp"; - - static String TEST1_PAT = "(DEBUG|INFO|WARN|ERROR|FATAL) - Message \\d"; - static String TEST8_PAT = "WARN org.apache.log4j.filter.SimpleFilterTest - Message \\d"; - static String EXCEPTION1 = "java.lang.Exception: Just testing"; - static String EXCEPTION2 = "\\s*at .*\\(.*:\\d{1,4}\\)"; - static String EXCEPTION3 = "\\s*at .*\\(Native Method\\)"; - - public SimpleFilterTest(String name) { - super(name); - } - - public void setUp() { - root = Logger.getRootLogger(); - logger = Logger.getLogger(SimpleFilterTest.class); - } - - public void tearDown() { - root.getLoggerRepository().resetConfiguration(); - } - - - public void test1() throws Exception { - JoranConfigurator joc = new JoranConfigurator(); - joc.doConfigure("./input/filter/simpleFilter1.xml", LogManager.getLoggerRepository()); - joc.dumpErrors(); - common(); - - ControlFilter cf = new ControlFilter(new String[]{TEST1_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3}); - - - Transformer.transform(TEMP, FILTERED, new Filter[] {cf, - new LineNumberFilter(), - new SunReflectFilter(), - new JunitTestRunnerFilter()}); - - assertTrue(Compare.compare(FILTERED, "witness/filter/simpleFilter.1")); - } - - public void test6() throws Exception { - JoranConfigurator joc = new JoranConfigurator(); - joc.doConfigure("./input/filter/simpleFilter6.xml", LogManager.getLoggerRepository()); - joc.dumpErrors(); - common(); - - ControlFilter cf = new ControlFilter(new String[]{TEST1_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3}); - - - Transformer.transform(TEMP, FILTERED, new Filter[] {cf, - new LineNumberFilter(), - new SunReflectFilter(), - new JunitTestRunnerFilter()}); - - assertTrue(Compare.compare(FILTERED, "witness/filter/simpleFilter.6")); - } - - public void test7() throws Exception { - JoranConfigurator joc = new JoranConfigurator(); - joc.doConfigure("./input/filter/simpleFilter7.xml", LogManager.getLoggerRepository()); - joc.dumpErrors(); - common(); - - ControlFilter cf = new ControlFilter(new String[]{TEST1_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3}); - - - Transformer.transform(TEMP, FILTERED, new Filter[] {cf, - new LineNumberFilter(), - new SunReflectFilter(), - new JunitTestRunnerFilter()}); - - assertTrue(Compare.compare(FILTERED, "witness/filter/simpleFilter.7")); - } - - public void test8() throws Exception { - JoranConfigurator joc = new JoranConfigurator(); - joc.doConfigure("./input/filter/simpleFilter8.xml", LogManager.getLoggerRepository()); - joc.dumpErrors(); - common(); - - ControlFilter cf = new ControlFilter(new String[]{TEST8_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3}); - - - Transformer.transform(TEMP, FILTERED, new Filter[] {cf, - new LineNumberFilter(), - new SunReflectFilter(), - new JunitTestRunnerFilter()}); - - assertTrue(Compare.compare(FILTERED, "witness/filter/simpleFilter.8")); - } - - public void test9() throws Exception { - JoranConfigurator joc = new JoranConfigurator(); - joc.doConfigure("./input/filter/simpleFilter9.xml", LogManager.getLoggerRepository()); - joc.dumpErrors(); - common(); - - ControlFilter cf = new ControlFilter(new String[]{TEST1_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3}); - - - Transformer.transform(TEMP, FILTERED, new Filter[] {cf, - new LineNumberFilter(), - new SunReflectFilter(), - new JunitTestRunnerFilter()}); - - assertTrue(Compare.compare(FILTERED, "witness/filter/simpleFilter.1")); - } - - public void test10() throws Exception { - JoranConfigurator joc = new JoranConfigurator(); - joc.doConfigure("./input/filter/simpleFilter10.xml", LogManager.getLoggerRepository()); - joc.dumpErrors(); - common(); - - ControlFilter cf = new ControlFilter(new String[]{TEST1_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3}); - - - Transformer.transform(TEMP, FILTERED, new Filter[] {cf, - new LineNumberFilter(), - new SunReflectFilter(), - new JunitTestRunnerFilter()}); - - assertTrue(Compare.compare(FILTERED, "witness/filter/simpleFilter.6")); - } - - public void test11() throws Exception { - JoranConfigurator joc = new JoranConfigurator(); - joc.doConfigure("./input/filter/simpleFilter11.xml", LogManager.getLoggerRepository()); - joc.dumpErrors(); - common(); - - ControlFilter cf = new ControlFilter(new String[]{TEST1_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3}); - - - Transformer.transform(TEMP, FILTERED, new Filter[] {cf, - new LineNumberFilter(), - new SunReflectFilter(), - new JunitTestRunnerFilter()}); - - assertTrue(Compare.compare(FILTERED, "witness/filter/simpleFilter.11")); - } - - public void test12() throws Exception { - JoranConfigurator joc = new JoranConfigurator(); - joc.doConfigure("./input/filter/simpleFilter12.xml", LogManager.getLoggerRepository()); - joc.dumpErrors(); - common(); - - ControlFilter cf = new ControlFilter(new String[]{TEST8_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3}); - - - Transformer.transform(TEMP, FILTERED, new Filter[] {cf, - new LineNumberFilter(), - new SunReflectFilter(), - new JunitTestRunnerFilter()}); - - assertTrue(Compare.compare(FILTERED, "witness/filter/simpleFilter.8")); - } - - - void common() { - int i = -1; - - logger.debug("Message " + ++i); - root.debug("Message " + i); - - logger.info ("Message " + ++i); - root.info("Message " + i); - - logger.warn ("Message " + ++i); - root.warn("Message " + i); - - logger.error("Message " + ++i); - root.error("Message " + i); - - logger.log(Level.FATAL, "Message " + ++i); - root.log(Level.FATAL, "Message " + i); - - Exception e = new Exception("Just testing"); - logger.debug("Message " + ++i, e); - root.debug("Message " + i, e); - - logger.error("Message " + ++i, e); - root.error("Message " + i, e); - } - -} diff --git a/tests/src/java/org/apache/log4j/helpers/BoundedFIFOTestCase.java b/tests/src/java/org/apache/log4j/helpers/BoundedFIFOTestCase.java index ca3816cd35..6fbfeb7ecf 100644 --- a/tests/src/java/org/apache/log4j/helpers/BoundedFIFOTestCase.java +++ b/tests/src/java/org/apache/log4j/helpers/BoundedFIFOTestCase.java @@ -15,19 +15,25 @@ * limitations under the License. */ - // // Log4j uses the JUnit framework for internal unit testing. JUnit // available from // // http://www.junit.org + + package org.apache.log4j.helpers; -import junit.framework.TestCase; -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.apache.log4j.helpers.BoundedFIFO; import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.Logger; +import org.apache.log4j.Level; + + +import junit.framework.TestCase; +import junit.framework.TestSuite; +import junit.framework.Test; + + /** @@ -36,197 +42,213 @@ @since 0.9.1 */ public class BoundedFIFOTestCase extends TestCase { static Logger cat = Logger.getLogger("x"); - static int MAX = 1000; + + static int MAX = 1000; + static LoggingEvent[] e = new LoggingEvent[MAX]; { for (int i = 0; i < MAX; i++) { - e[i] = new LoggingEvent("", cat, Level.DEBUG, "e" + i, null); + e[i] = new LoggingEvent("", cat, Level.DEBUG, "e"+i, null); } } + public BoundedFIFOTestCase(String name) { super(name); } - public void setUp() { + + public + void setUp() { + } + /** Pattern: +++++..-----.. */ - public void test1() { - for (int size = 1; size <= 128; size *= 2) { + public + void test1() { + for(int size = 1; size <= 128; size *=2) { BoundedFIFO bf = new BoundedFIFO(size); - + assertEquals(bf.getMaxSize(), size); assertNull(bf.get()); - + int i; int j; int k; - for (i = 1; i < (2 * size); i++) { - for (j = 0; j < i; j++) { - //System.out.println("Putting "+e[j]); - bf.put(e[j]); - assertEquals(bf.length(), (j < size) ? (j + 1) : size); - } - - int max = (size < j) ? size : j; - j--; - - for (k = 0; k <= j; k++) { - //System.out.println("max="+max+", j="+j+", k="+k); - assertEquals(bf.length(), ((max - k) > 0) ? (max - k) : 0); - - Object r = bf.get(); - - //System.out.println("Got "+r); - if (k >= size) { - assertNull(r); - } else { - assertEquals(r, e[k]); - } - } + for(i = 1; i < 2*size; i++) { + for(j = 0; j < i; j++) { + //System.out.println("Putting "+e[j]); + bf.put(e[j]); assertEquals(bf.length(), j < size ? j+1 : size); + } + int max = size < j ? size : j; + j--; + for(k = 0; k <= j; k++) { + //System.out.println("max="+max+", j="+j+", k="+k); + assertEquals(bf.length(), max - k > 0 ? max - k : 0); + Object r = bf.get(); + //System.out.println("Got "+r); + if(k >= size) { + assertNull(r); + } else { + assertEquals(r, e[k]); + } + } } - //System.out.println("Passed size="+size); } } + /** Pattern: ++++--++--++ */ - public void test2() { + public + void test2() { int size = 3; BoundedFIFO bf = new BoundedFIFO(size); - - bf.put(e[0]); + + bf.put(e[0]); assertEquals(bf.get(), e[0]); assertNull(bf.get()); - bf.put(e[1]); - assertEquals(bf.length(), 1); - bf.put(e[2]); - assertEquals(bf.length(), 2); - bf.put(e[3]); - assertEquals(bf.length(), 3); - assertEquals(bf.get(), e[1]); - assertEquals(bf.length(), 2); - assertEquals(bf.get(), e[2]); - assertEquals(bf.length(), 1); - assertEquals(bf.get(), e[3]); - assertEquals(bf.length(), 0); - assertNull(bf.get()); - assertEquals(bf.length(), 0); + bf.put(e[1]); assertEquals(bf.length(), 1); + bf.put(e[2]); assertEquals(bf.length(), 2); + bf.put(e[3]); assertEquals(bf.length(), 3); + assertEquals(bf.get(), e[1]); assertEquals(bf.length(), 2); + assertEquals(bf.get(), e[2]); assertEquals(bf.length(), 1); + assertEquals(bf.get(), e[3]); assertEquals(bf.length(), 0); + assertNull(bf.get()); assertEquals(bf.length(), 0); } int min(int a, int b) { - return (a < b) ? a : b; + return a < b ? a : b; } + /** Pattern ++++++++++++++++++++ (insert only); */ - public void testResize1() { + public + void testResize1() { int size = 10; - for (int n = 1; n < (size * 2); n++) { - for (int i = 0; i < (size * 2); i++) { - BoundedFIFO bf = new BoundedFIFO(size); + for(int n = 1; n < size*2; n++) { + for(int i = 0; i < size*2; i++) { - for (int f = 0; f < i; f++) { + BoundedFIFO bf = new BoundedFIFO(size); + for(int f = 0; f < i; f++) { bf.put(e[f]); } bf.resize(n); - int expectedSize = min(n, min(i, size)); assertEquals(bf.length(), expectedSize); - - for (int c = 0; c < expectedSize; c++) { + for(int c = 0; c < expectedSize; c++) { assertEquals(bf.get(), e[c]); } } } } + + /** Pattern ++...+ --...- */ - public void testResize2() { + public + void testResize2() { int size = 10; - for (int n = 1; n < (size * 2); n++) { - for (int i = 0; i < (size * 2); i++) { - for (int d = 0; d < min(i, size); d++) { - BoundedFIFO bf = new BoundedFIFO(size); - - for (int p = 0; p < i; p++) { - bf.put(e[p]); - } + for(int n = 1; n < size*2; n++) { + for(int i = 0; i < size*2; i++) { + for(int d = 0; d < min(i,size); d++) { + + BoundedFIFO bf = new BoundedFIFO(size); + for(int p = 0; p < i; p++) { + bf.put(e[p]); + } - for (int g = 0; g < d; g++) { - bf.get(); - } + for(int g = 0; g < d; g++) { + bf.get(); + } - // x = the number of elems in - int x = bf.length(); + // x = the number of elems in + int x = bf.length(); - bf.resize(n); + bf.resize(n); - int expectedSize = min(n, x); - assertEquals(bf.length(), expectedSize); + int expectedSize = min(n, x); + assertEquals(bf.length(), expectedSize); - for (int c = 0; c < expectedSize; c++) { - assertEquals(bf.get(), e[c + d]); - } - - assertNull(bf.get()); - } + for(int c = 0; c < expectedSize; c++) { + assertEquals(bf.get(), e[c+d]); + } + assertNull(bf.get()); + } } } } + /** Pattern: i inserts, d deletes, r inserts */ - public void testResize3() { + public + void testResize3() { int size = 10; - for (int n = 1; n < (size * 2); n++) { - for (int i = 0; i < size; i++) { - for (int d = 0; d < i; d++) { - for (int r = 0; r < d; r++) { - BoundedFIFO bf = new BoundedFIFO(size); - - for (int p0 = 0; p0 < i; p0++) - bf.put(e[p0]); - - for (int g = 0; g < d; g++) - bf.get(); - - for (int p1 = 0; p1 < r; p1++) - bf.put(e[i + p1]); + for(int n = 1; n < size*2; n++) { + for(int i = 0; i < size; i++) { + for(int d = 0; d < i; d++) { + for(int r = 0; r < d; r++) { + + BoundedFIFO bf = new BoundedFIFO(size); + for(int p0 = 0; p0 < i; p0++) { + bf.put(e[p0]); + } - int x = bf.length(); + for(int g = 0; g < d; g++) { + bf.get(); + } + for(int p1 = 0; p1 < r; p1++) { + bf.put(e[i+p1]); + } + - bf.resize(n); + + int x = bf.length(); - int expectedSize = min(n, x); - assertEquals(bf.length(), expectedSize); + bf.resize(n); + - for (int c = 0; c < expectedSize; c++) { - assertEquals(bf.get(), e[c + d]); - } + int expectedSize = min(n, x); + assertEquals(bf.length(), expectedSize); - //assertNull(bf.get()); - } - } + for(int c = 0; c < expectedSize; c++) { + assertEquals(bf.get(), e[c+d]); + } + //assertNull(bf.get()); + } + } } } } - + + public + static + Test suite() { + TestSuite suite = new TestSuite(); + suite.addTest(new BoundedFIFOTestCase("test1")); + suite.addTest(new BoundedFIFOTestCase("test2")); + suite.addTest(new BoundedFIFOTestCase("testResize1")); + suite.addTest(new BoundedFIFOTestCase("testResize2")); + suite.addTest(new BoundedFIFOTestCase("testResize3")); + return suite; + } } diff --git a/tests/src/java/org/apache/log4j/helpers/CyclicBufferTestCase.java b/tests/src/java/org/apache/log4j/helpers/CyclicBufferTestCase.java index 164d21996d..07271f767f 100644 --- a/tests/src/java/org/apache/log4j/helpers/CyclicBufferTestCase.java +++ b/tests/src/java/org/apache/log4j/helpers/CyclicBufferTestCase.java @@ -15,23 +15,22 @@ * limitations under the License. */ - // // Log4j uses the JUnit framework for internal unit testing. JUnit // available from // // http://www.junit.org -package org.apache.log4j.helpers; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.apache.log4j.helpers.CyclicBuffer; +package org.apache.log4j.helpers; + import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.Logger; +import org.apache.log4j.Level; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import junit.framework.Test; /** Unit test the {@link CyclicBuffer}. @@ -40,54 +39,63 @@ */ public class CyclicBufferTestCase extends TestCase { - static Logger logger = Logger.getLogger("x"); + + static Logger cat = Logger.getLogger("x"); + static int MAX = 1000; + static LoggingEvent[] e = new LoggingEvent[MAX]; { for (int i = 0; i < MAX; i++) { - e[i] = new LoggingEvent("", logger, Level.DEBUG, "e" + i, null); + e[i] = new LoggingEvent("", cat, Level.DEBUG, "e"+i, null); } } + public CyclicBufferTestCase(String name) { super(name); } - public void setUp() { + + public + void setUp() { + } - public void test0() { + + public + void test0() { int size = 2; - CyclicBuffer cb = new CyclicBuffer(size); - assertEquals(cb.getMaxSize(), size); + CyclicBuffer cb = new CyclicBuffer(size); + assertEquals(cb.getMaxSize(), size); cb.add(e[0]); - assertEquals(cb.length(), 1); - assertEquals(cb.get(), e[0]); - assertEquals(cb.length(), 0); - assertNull(cb.get()); - assertEquals(cb.length(), 0); + assertEquals(cb.length(), 1); + assertEquals(cb.get(), e[0]); assertEquals(cb.length(), 0); + assertNull(cb.get()); assertEquals(cb.length(), 0); + - cb = new CyclicBuffer(size); + cb = new CyclicBuffer(size); cb.add(e[0]); cb.add(e[1]); - assertEquals(cb.length(), 2); - assertEquals(cb.get(), e[0]); - assertEquals(cb.length(), 1); - assertEquals(cb.get(), e[1]); - assertEquals(cb.length(), 0); - assertNull(cb.get()); - assertEquals(cb.length(), 0); - } + assertEquals(cb.length(), 2); + assertEquals(cb.get(), e[0]); assertEquals(cb.length(), 1); + assertEquals(cb.get(), e[1]); assertEquals(cb.length(), 0); + assertNull(cb.get()); assertEquals(cb.length(), 0); + + } + /** Test a buffer of size 1,2,4,8,..,128 */ - public void test1() { - for (int bufSize = 1; bufSize <= 128; bufSize *= 2) - doTest1(bufSize); + public + void test1() { + for(int bufSize = 1; bufSize <= 128; bufSize *=2) { + doTest1(bufSize); + } } void doTest1(int size) { @@ -96,67 +104,66 @@ void doTest1(int size) { assertEquals(cb.getMaxSize(), size); - for (int i = -(size + 10); i < (size + 10); i++) { + for(int i = -(size+10); i < (size+10); i++) { assertNull(cb.get(i)); } - - for (int i = 0; i < MAX; i++) { + + for(int i = 0; i < MAX; i++) { cb.add(e[i]); - - int limit = (i < (size - 1)) ? i : (size - 1); + int limit = i < size-1 ? i : size-1; //System.out.println("\nLimit is " + limit + ", i="+i); - for (int j = limit; j >= 0; j--) { - //System.out.println("i= "+i+", j="+j); - assertEquals(cb.get(j), e[i - (limit - j)]); - } + for(int j = limit; j >= 0; j--) { + //System.out.println("i= "+i+", j="+j); + assertEquals(cb.get(j), e[i-(limit-j)]); + } assertNull(cb.get(-1)); - assertNull(cb.get(limit + 1)); + assertNull(cb.get(limit+1)); } } - public void testResize() { - for (int isize = 1; isize <= 128; isize *= 2) { - doTestResize(isize, (isize / 2) + 1, (isize / 2) + 1); - doTestResize(isize, (isize / 2) + 1, isize + 10); - doTestResize(isize, isize + 10, (isize / 2) + 1); - doTestResize(isize, isize + 10, isize + 10); + public + void testResize() { + for(int isize = 1; isize <= 128; isize *=2) { + doTestResize(isize, isize/2+1, isize/2+1); + doTestResize(isize, isize/2+1, isize+10); + doTestResize(isize, isize+10, isize/2+1); + doTestResize(isize, isize+10, isize+10); } } - + void doTestResize(int initialSize, int numberOfAdds, int newSize) { //System.out.println("initialSize = "+initialSize+", numberOfAdds=" // +numberOfAdds+", newSize="+newSize); CyclicBuffer cb = new CyclicBuffer(initialSize); - - for (int i = 0; i < numberOfAdds; i++) { + for(int i = 0; i < numberOfAdds; i++) { cb.add(e[i]); - } - + } cb.resize(newSize); int offset = numberOfAdds - initialSize; - - if (offset < 0) { - offset = 0; + if(offset< 0) { + offset = 0; } - int len = (newSize < numberOfAdds) ? newSize : numberOfAdds; - len = (len < initialSize) ? len : initialSize; - + int len = newSize < numberOfAdds ? newSize : numberOfAdds; + len = len < initialSize ? len : initialSize; //System.out.println("Len = "+len+", offset="+offset); - for (int j = 0; j < len; j++) { - assertEquals(cb.get(j), e[offset + j]); + for(int j = 0; j < len; j++) { + assertEquals(cb.get(j), e[offset+j]); } + } + - public static Test suite() { + public + static + Test suite() { TestSuite suite = new TestSuite(); suite.addTest(new CyclicBufferTestCase("test0")); suite.addTest(new CyclicBufferTestCase("test1")); suite.addTest(new CyclicBufferTestCase("testResize")); - return suite; } } diff --git a/tests/src/java/org/apache/log4j/helpers/DateLayoutTest.java b/tests/src/java/org/apache/log4j/helpers/DateLayoutTest.java index 0be379d7fb..2b4056fc11 100644 --- a/tests/src/java/org/apache/log4j/helpers/DateLayoutTest.java +++ b/tests/src/java/org/apache/log4j/helpers/DateLayoutTest.java @@ -24,15 +24,13 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Locale; import java.util.TimeZone; -import java.util.Date; +import java.util.Calendar; /** * Tests for DateLayout. - * @deprecated since DateLayout is deprecated. + * */ public class DateLayoutTest extends LayoutTest { /** @@ -69,7 +67,6 @@ protected Layout createLayout() { /** * Tests DateLayout.NULL_DATE_FORMAT constant. - * @deprecated since DateLayout is deprecated. */ public void testNullDateFormat() { assertEquals("NULL", DateLayout.NULL_DATE_FORMAT); @@ -77,7 +74,6 @@ public void testNullDateFormat() { /** * Tests DateLayout.RELATIVE constant. - * @deprecated since DateLayout is deprecated. */ public void testRelativeTimeDateFormat() { assertEquals("RELATIVE", DateLayout.RELATIVE_TIME_DATE_FORMAT); @@ -131,7 +127,6 @@ public void testSetOptionTimeZone() { /** * Tests setDateFormat. - * @deprecated since DateLayout is deprecated. */ public void testSetDateFormat() { DateLayout layout = (DateLayout) createLayout(); @@ -141,7 +136,6 @@ public void testSetDateFormat() { /** * Tests setTimeZone. - * @deprecated since DateLayout is deprecated. */ public void testSetTimeZone() { DateLayout layout = (DateLayout) createLayout(); @@ -151,7 +145,6 @@ public void testSetTimeZone() { /** * Tests 2 parameter setDateFormat with null. - * @deprecated since DateLayout is deprecated. */ public void testSetDateFormatNull() { DateLayout layout = (DateLayout) createLayout(); @@ -160,7 +153,6 @@ public void testSetDateFormatNull() { /** * Tests 2 parameter setDateFormat with "NULL". - * @deprecated since DateLayout is deprecated. */ public void testSetDateFormatNullString() { DateLayout layout = (DateLayout) createLayout(); @@ -169,7 +161,6 @@ public void testSetDateFormatNullString() { /** * Tests 2 parameter setDateFormat with "RELATIVE". - * @deprecated since DateLayout is deprecated. */ public void testSetDateFormatRelative() { DateLayout layout = (DateLayout) createLayout(); @@ -178,7 +169,6 @@ public void testSetDateFormatRelative() { /** * Tests 2 parameter setDateFormat with "ABSOLUTE". - * @deprecated since DateLayout is deprecated. */ public void testSetDateFormatAbsolute() { DateLayout layout = (DateLayout) createLayout(); @@ -187,7 +177,6 @@ public void testSetDateFormatAbsolute() { /** * Tests 2 parameter setDateFormat with "DATETIME". - * @deprecated since DateLayout is deprecated. */ public void testSetDateFormatDateTime() { DateLayout layout = (DateLayout) createLayout(); @@ -196,7 +185,6 @@ public void testSetDateFormatDateTime() { /** * Tests 2 parameter setDateFormat with "ISO8601". - * @deprecated since DateLayout is deprecated. */ public void testSetDateFormatISO8601() { DateLayout layout = (DateLayout) createLayout(); @@ -205,7 +193,6 @@ public void testSetDateFormatISO8601() { /** * Tests 2 parameter setDateFormat with "HH:mm:ss". - * @deprecated since DateLayout is deprecated. */ public void testSetDateFormatSimple() { DateLayout layout = (DateLayout) createLayout(); @@ -214,7 +201,6 @@ public void testSetDateFormatSimple() { /** * Tests activateOptions. - * @deprecated since DateLayout is deprecated. */ public void testActivateOptions() { DateLayout layout = (DateLayout) createLayout(); @@ -225,7 +211,6 @@ public void testActivateOptions() { /** * Tests setDateFormat(DateFormat, TimeZone). - * @deprecated since DateLayout is deprecated. */ public void testSetDateFormatWithFormat() { DateFormat format = new SimpleDateFormat("HH:mm"); @@ -233,6 +218,7 @@ public void testSetDateFormatWithFormat() { layout.setDateFormat(format, TimeZone.getDefault()); } + /** * Tests IS08601DateFormat class. * @deprecated since ISO8601DateFormat is deprecated @@ -261,10 +247,8 @@ public void testDateTimeFormat() { assertEquals(expected, actual); } - /** * Concrete Layout class for tests. - * @deprecated */ private static final class MockLayout extends DateLayout { /** diff --git a/tests/src/java/org/apache/log4j/helpers/LevelOptionConverterTest.java b/tests/src/java/org/apache/log4j/helpers/LevelOptionConverterTest.java deleted file mode 100644 index cbf3673eea..0000000000 --- a/tests/src/java/org/apache/log4j/helpers/LevelOptionConverterTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.helpers; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.apache.log4j.Level; -import org.apache.log4j.helpers.OptionConverter; -import org.apache.log4j.xml.XLevel; - -import java.util.Properties; - - -/** - * Test variable substitution code. - * - * @author Ceki Gülcü -*/ -public class LevelOptionConverterTest extends TestCase { - Properties props; - - public LevelOptionConverterTest(String name) { - super(name); - } - - public void setUp() { - } - - public void tearDown() { - props = null; - } - - public void toLevelTest1() { - String val = "INFO"; - Level p = OptionConverter.toLevel(val, null); - assertEquals(p, Level.INFO); - } - - public void toLevelTest2() { - String val = "INFO#org.apache.log4j.xml.XLevel"; - Level p = OptionConverter.toLevel(val, null); - assertEquals(p, Level.INFO); - } - - public void toLevelTest3() { - String val = "TRACE#org.apache.log4j.xml.XLevel"; - Level p = OptionConverter.toLevel(val, null); - assertEquals(p, XLevel.TRACE); - } - - public void toLevelTest4() { - String val = "TR#org.apache.log4j.xml.XLevel"; - Level p = OptionConverter.toLevel(val, null); - assertEquals(p, null); - } - - public void toLevelTest5() { - String val = "INFO#org.apache.log4j.xml.TOTO"; - Level p = OptionConverter.toLevel(val, null); - assertEquals(p, null); - } - - public static Test suite() { - TestSuite suite = new TestSuite(); - suite.addTest(new LevelOptionConverterTest("toLevelTest1")); - suite.addTest(new LevelOptionConverterTest("toLevelTest2")); - suite.addTest(new LevelOptionConverterTest("toLevelTest3")); - suite.addTest(new LevelOptionConverterTest("toLevelTest4")); - suite.addTest(new LevelOptionConverterTest("toLevelTest5")); - return suite; - } -} diff --git a/tests/src/java/org/apache/log4j/helpers/OptionConverterTestCase.java b/tests/src/java/org/apache/log4j/helpers/OptionConverterTestCase.java new file mode 100644 index 0000000000..faef415568 --- /dev/null +++ b/tests/src/java/org/apache/log4j/helpers/OptionConverterTestCase.java @@ -0,0 +1,199 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Log4j uses the JUnit framework for internal unit testing. JUnit +// is available from "http://www.junit.org". + +package org.apache.log4j.helpers; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Properties; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.apache.log4j.Level; +import org.apache.log4j.LogManager; +import org.apache.log4j.PropertyConfiguratorTest; +import org.apache.log4j.xml.XLevel; + +/** + Test variable substitution code. + @author Ceki Gülcü + + @since 1.0 +*/ +public class OptionConverterTestCase extends TestCase { + + Properties props; + + public OptionConverterTestCase(String name) { + super(name); + } + + public + void setUp() { + props = new Properties(); + props.put("TOTO", "wonderful"); + props.put("key1", "value1"); + props.put("key2", "value2"); + // Log4J will NPE without this: + props.put("line.separator", System.getProperty("line.separator")); + // Log4J will throw an Error without this: + props.put("java.home", System.getProperty("java.home")); + System.setProperties(props); + + + } + + public + void tearDown() { + props = null; + LogManager.resetConfiguration(); + } + + public + void varSubstTest1() { + String r; + + r = OptionConverter.substVars("hello world.", null); + assertEquals("hello world.", r); + + r = OptionConverter.substVars("hello ${TOTO} world.", null); + + assertEquals("hello wonderful world.", r); + } + + + public + void varSubstTest2() { + String r; + + r = OptionConverter.substVars("Test2 ${key1} mid ${key2} end.", null); + assertEquals("Test2 value1 mid value2 end.", r); + } + + public + void varSubstTest3() { + String r; + + r = OptionConverter.substVars( + "Test3 ${unset} mid ${key1} end.", null); + assertEquals("Test3 mid value1 end.", r); + } + + public + void varSubstTest4() { + String val = "Test4 ${incomplete "; + try { + OptionConverter.substVars(val, null); + } + catch(IllegalArgumentException e) { + String errorMsg = e.getMessage(); + //System.out.println('['+errorMsg+']'); + assertEquals('"'+val + + "\" has no closing brace. Opening brace at position 6.", + errorMsg); + } + } + + public + void varSubstTest5() { + Properties props = new Properties(); + props.put("p1", "x1"); + props.put("p2", "${p1}"); + String res = OptionConverter.substVars("${p2}", props); + System.out.println("Result is ["+res+"]."); + assertEquals(res, "x1"); + } + + /** + * Tests configuring Log4J from an InputStream. + * + * @since 1.2.17 + */ + public void testInputStream() throws IOException { + File file = new File("input/filter1.properties"); + assertTrue(file.exists()); + FileInputStream inputStream = new FileInputStream(file); + try { + OptionConverter.selectAndConfigure(inputStream, null, LogManager.getLoggerRepository()); + } finally { + inputStream.close(); + } + new PropertyConfiguratorTest(this.getClass().getName()).validateNested(); + } + + public + void toLevelTest1() { + String val = "INFO"; + Level p = OptionConverter.toLevel(val, null); + assertEquals(p, Level.INFO); + } + + public + void toLevelTest2() { + String val = "INFO#org.apache.log4j.xml.XLevel"; + Level p = OptionConverter.toLevel(val, null); + assertEquals(p, Level.INFO); + } + + public + void toLevelTest3() { + String val = "TRACE#org.apache.log4j.xml.XLevel"; + Level p = OptionConverter.toLevel(val, null); + assertEquals(p, XLevel.TRACE); + } + + public + void toLevelTest4() { + String val = "TR#org.apache.log4j.xml.XLevel"; + Level p = OptionConverter.toLevel(val, null); + assertEquals(p, null); + } + + public + void toLevelTest5() { + String val = "INFO#org.apache.log4j.xml.TOTO"; + Level p = OptionConverter.toLevel(val, null); + assertEquals(p, null); + } + + public + static + Test suite() { + TestSuite suite = new TestSuite(); + suite.addTest(new OptionConverterTestCase("varSubstTest5")); + suite.addTest(new OptionConverterTestCase("varSubstTest1")); + suite.addTest(new OptionConverterTestCase("varSubstTest2")); + suite.addTest(new OptionConverterTestCase("varSubstTest3")); + suite.addTest(new OptionConverterTestCase("varSubstTest4")); + + suite.addTest(new OptionConverterTestCase("testInputStream")); + + suite.addTest(new OptionConverterTestCase("toLevelTest1")); + suite.addTest(new OptionConverterTestCase("toLevelTest2")); + suite.addTest(new OptionConverterTestCase("toLevelTest3")); + suite.addTest(new OptionConverterTestCase("toLevelTest4")); + suite.addTest(new OptionConverterTestCase("toLevelTest5")); + return suite; + } + +} diff --git a/tests/src/java/org/apache/log4j/helpers/OptionSubstitutionTest.java b/tests/src/java/org/apache/log4j/helpers/OptionSubstitutionTest.java deleted file mode 100644 index 0eb0b6f1bf..0000000000 --- a/tests/src/java/org/apache/log4j/helpers/OptionSubstitutionTest.java +++ /dev/null @@ -1,168 +0,0 @@ -package org.apache.log4j.helpers; - - -import junit.framework.TestCase; -import junit.framework.TestSuite; -import junit.framework.Test; -import java.util.Properties; - -/** - * Test variable substitution code in OptionConverter.substVars method. - * - * @author Ceki Gülcü - * - * @since 1.0 - */ -public class OptionSubstitutionTest extends TestCase { - - Properties props; - - public OptionSubstitutionTest(String name) { - super(name); - } - - public void setUp() { - props = new Properties(); - props.put("TOTO", "wonderful"); - props.put("key1", "value1"); - props.put("key2", "value2"); - System.setProperties(props); - - } - - public void tearDown() { - props = null; - } - - public void testVarSubst1() { - String r; - - r = OptionConverter.substVars("hello world.", null); - assertEquals("hello world.", r); - - r = OptionConverter.substVars("hello ${TOTO} world.", null); - - assertEquals("hello wonderful world.", r); - } - - public void testVarSubst2() { - String r; - - r = OptionConverter.substVars("Test2 ${key1} mid ${key2} end.", null); - assertEquals("Test2 value1 mid value2 end.", r); - } - - public void testVarSubst3() { - String r; - - r = OptionConverter.substVars("Test3 ${unset} mid ${key1} end.", null); - assertEquals("Test3 mid value1 end.", r); - } - - public void testVarSubst4() { - String res; - String val = "Test4 ${incomplete "; - try { - res = OptionConverter.substVars(val, null); - } catch (IllegalArgumentException e) { - String errorMsg = e.getMessage(); - //System.out.println('['+errorMsg+']'); - assertEquals('"' + val - + "\" has no closing brace. Opening brace at position 6.", errorMsg); - } - } - - /** - * Test recursive variable substitution. - */ - public void testRecursiveVarSubst() { - Properties props = new Properties(); - props.put("p1", "x1"); - props.put("p2", "${p1}"); - String res = OptionConverter.substVars("${p2}", props); - System.out.println("Result is [" + res + "]."); - assertEquals("x1", res); - } - - /** - * In this test we check wheter the :- operator substitutes the default value - * when the properties does not contain a value for the substitution key. - * - */ - public void testVarSubstWithDefault1() { - Properties props = new Properties(); - String res = OptionConverter.substVars("HELLO ${name:-world}.", props); - System.out.println("Result is [" + res + "]."); - assertEquals("HELLO world.", res); - } - - - /** - * In this test we check wheter the :- operator substitutes the default value - * when the properties does not contain a value for the substitution key. - * - */ - public void testVarSubstWithDefault2() { - Properties props = new Properties(); - props.put("name", "John"); - String res = OptionConverter.substVars("HELLO ${name:-world}.", props); - System.out.println("Result is [" + res + "]."); - assertEquals("HELLO John.", res); - } - - /** - * Test whether recursive substitution works recursively - * - */ - public void testRecursiveVarSubstWithDefault() { - Properties props = new Properties(); - props.put("p1", "${name:-world}"); - String res = OptionConverter.substVars("HELLO ${p1}.", props); - //System.out.println("Result is [" + res + "]."); - assertEquals("HELLO world.", res); - - props.put("name", "John"); - res = OptionConverter.substVars("HELLO ${p1}.", props); - //System.out.println("Result is [" + res + "]."); - assertEquals("HELLO John.", res); - } - - /** - * Tests FileAppender.stripDuplicateBackslashes. - * @remarks This should be moved to a FileAppenderTestCase - * - * @since 1.3 - */ - public void testStripDuplicateBackslashes() { - assertEquals("\\foo\\bar\\foo", OptionConverter.stripDuplicateBackslashes("\\foo\\bar\\foo")); - assertEquals("\\foo\\bar\\foo\\", OptionConverter.stripDuplicateBackslashes("\\\\foo\\\\bar\\\\foo\\\\")); - assertEquals("\\foo\\bar\\foo\\", OptionConverter.stripDuplicateBackslashes("\\foo\\bar\\foo\\")); - // - // UNC's should either start with two backslashes and contain additional singles - // or four back slashes and addition doubles - assertEquals("\\\\foo\\bar\\foo", OptionConverter.stripDuplicateBackslashes("\\\\\\\\foo\\\\bar\\\\foo")); - assertEquals("\\\\foo\\bar\\foo", OptionConverter.stripDuplicateBackslashes("\\\\foo\\bar\\foo")); - // - // it it starts with doubles but has no other path component - // then it is a file path - assertEquals("\\foo.log", OptionConverter.stripDuplicateBackslashes("\\\\foo.log")); - // - // it it starts with quads but has no other path component - // then it is a UNC - assertEquals("\\\\foo.log", OptionConverter.stripDuplicateBackslashes("\\\\\\\\foo.log")); - } - - - public static Test Xsuite() { - TestSuite suite = new TestSuite(); -// suite.addTest(new OptionSubstitutionTest("testVarSubst1")); -// suite.addTest(new OptionSubstitutionTest("testVarSubst2")); -// suite.addTest(new OptionSubstitutionTest("testVarSubst3")); -// suite.addTest(new OptionSubstitutionTest("testVarSubst4")); -// suite.addTest(new OptionSubstitutionTest("testRecursiveVarSubst")); - suite.addTest(new OptionSubstitutionTest("testVarSubstWithDefault1")); - suite.addTest(new OptionSubstitutionTest("testVarSubstWithDefault2")); - return suite; - } - -} \ No newline at end of file diff --git a/tests/src/java/org/apache/log4j/helpers/PatternParserTestCase.java b/tests/src/java/org/apache/log4j/helpers/PatternParserTestCase.java new file mode 100644 index 0000000000..872e15faa0 --- /dev/null +++ b/tests/src/java/org/apache/log4j/helpers/PatternParserTestCase.java @@ -0,0 +1,136 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.helpers; + +import junit.framework.TestCase; +import junit.framework.TestSuite; +import junit.framework.Test; + +import org.apache.log4j.Logger; +import org.apache.log4j.Level; +import org.apache.log4j.Appender; +import org.apache.log4j.FileAppender; +import org.apache.log4j.PatternLayout; +import org.apache.log4j.MDC; + +import org.apache.log4j.util.Compare; + +/** + Test case for helpers/PatternParser.java. Tests the various + conversion patterns supported by PatternParser. This test + class tests PatternParser via the PatternLayout class which + uses it. + */ +public class PatternParserTestCase extends TestCase { + + static String OUTPUT_FILE = "output/PatternParser"; + static String WITNESS_FILE = "witness/PatternParser"; + + static String msgPattern = "%m%n"; + + Logger root; + Logger logger; + + public PatternParserTestCase(String name) { + super(name); + } + + public void setUp() { + root = Logger.getRootLogger(); + root.removeAllAppenders(); + } + + public void tearDown() { + root.getLoggerRepository().resetConfiguration(); + } + + /** + Test case for MDC conversion pattern. */ + public void mdcPattern() throws Exception { + + String mdcMsgPattern1 = "%m : %X%n"; + String mdcMsgPattern2 = "%m : %X{key1}%n"; + String mdcMsgPattern3 = "%m : %X{key2}%n"; + String mdcMsgPattern4 = "%m : %X{key3}%n"; + String mdcMsgPattern5 = "%m : %X{key1},%X{key2},%X{key3}%n"; + + // set up appender + PatternLayout layout = new PatternLayout(msgPattern); + Appender appender = new FileAppender(layout, OUTPUT_FILE+"_mdc", false); + + // set appender on root and set level to debug + root.addAppender(appender); + root.setLevel(Level.DEBUG); + + // output starting message + root.debug("starting mdc pattern test"); + + layout.setConversionPattern(mdcMsgPattern1); + root.debug("empty mdc, no key specified in pattern"); + + layout.setConversionPattern(mdcMsgPattern2); + root.debug("empty mdc, key1 in pattern"); + + layout.setConversionPattern(mdcMsgPattern3); + root.debug("empty mdc, key2 in pattern"); + + layout.setConversionPattern(mdcMsgPattern4); + root.debug("empty mdc, key3 in pattern"); + + layout.setConversionPattern(mdcMsgPattern5); + root.debug("empty mdc, key1, key2, and key3 in pattern"); + + MDC.put("key1", "value1"); + MDC.put("key2", "value2"); + + layout.setConversionPattern(mdcMsgPattern1); + root.debug("filled mdc, no key specified in pattern"); + + layout.setConversionPattern(mdcMsgPattern2); + root.debug("filled mdc, key1 in pattern"); + + layout.setConversionPattern(mdcMsgPattern3); + root.debug("filled mdc, key2 in pattern"); + + layout.setConversionPattern(mdcMsgPattern4); + root.debug("filled mdc, key3 in pattern"); + + layout.setConversionPattern(mdcMsgPattern5); + root.debug("filled mdc, key1, key2, and key3 in pattern"); + + MDC.remove("key1"); + MDC.remove("key2"); + + layout.setConversionPattern(msgPattern); + root.debug("finished mdc pattern test"); + + assertTrue(Compare.compare(OUTPUT_FILE+"_mdc", WITNESS_FILE+"_mdc")); + } + + public static Test suite() { + TestSuite suite = new TestSuite(); + // + // MDC requires JDK 1.2+ + // + if (!System.getProperty("java.version").startsWith("1.1.")) { + suite.addTest(new PatternParserTestCase("mdcPattern")); + } + return suite; + } + +} diff --git a/tests/src/java/org/apache/log4j/helpers/ReaderWriterLockTestCase.java b/tests/src/java/org/apache/log4j/helpers/ReaderWriterLockTestCase.java deleted file mode 100644 index 79a90a2d87..0000000000 --- a/tests/src/java/org/apache/log4j/helpers/ReaderWriterLockTestCase.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.helpers; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import java.io.BufferedReader; -import java.io.PipedReader; -import java.io.PipedWriter; -import java.io.PrintWriter; - - -/** - * This test checks the correctness of ReaderWriterLock. - * - * Warning This test should not use log4j loggers. - * - * There is not much point in having a test depend on the component being tested. - * - * @author Ceki Gülcü - * - */ -public class ReaderWriterLockTestCase extends TestCase { - static final int NUM_READERS = 120; //120; - static final int NUM_WRITERS = 4; //4; - static long WLOOP; // number of repetitions for writer threads - static long RLOOP; // number of repetitions for reader threads - double value1 = 0; - double value2 = 0; - - // this is the object we are testing: - ReaderWriterLock lock; - - // The bufferedReader will be passed to the VerifierThread - BufferedReader bufferedReader; - - // This is wehere readers and writers send their output - PrintWriter printWriter; - - /** - * Constructor for ReaderWriterLockTestCase. - * @param arg0 - */ - public ReaderWriterLockTestCase(String arg0) { - super(arg0); - } - - protected void setUp() throws Exception { - // We write to a piped buffer so that a verifer thread can check the output - PipedWriter pipedWriter = new PipedWriter(); - PipedReader pipedReader = new PipedReader(); - bufferedReader = new BufferedReader(pipedReader); - pipedReader.connect(pipedWriter); - - printWriter = new PrintWriter(pipedWriter); - lock = new ReaderWriterLock(printWriter); - } - - protected void tearDown() throws Exception { - } - - public void test1() throws Exception { - WLOOP = Long.parseLong(System.getProperty("runLen")); - RLOOP = (long) (WLOOP * (1.0)); // readers loop longer - - Thread[] threads = new Thread[NUM_READERS + NUM_WRITERS]; - - VerifierThread vt = - new VerifierThread(bufferedReader, NUM_READERS, NUM_WRITERS); - vt.start(); - - for (int i = 0; i < NUM_READERS; i++) { - threads[i] = new ReaderThread(i, vt); - } - - for (int i = 0; i < NUM_WRITERS; i++) { - threads[NUM_READERS + i] = new WriterThread(i, vt); - } - - for (int i = 0; i < (NUM_WRITERS + NUM_READERS); i++) { - threads[i].start(); - } - - // It's better to wait for the writer to finish first - for (int i = 0; i < (NUM_WRITERS + NUM_READERS); i++) { - try { - threads[i].join(); - } catch (InterruptedException e) { - } - } - - // let the verifier thread close - vt.closed = true; - - Exception e = vt.getException(); - - if (e != null) { - throw e; - } - } - - void delay(long delay) { - try { - Thread.sleep(delay); - } catch (InterruptedException e) { - } - } - - public static Test suite() { - TestSuite suite = new TestSuite(); - suite.addTest(new ReaderWriterLockTestCase("test1")); - - return suite; - } - - void printMessage(String msg) { - //printWriter.print("["); - printWriter.println(Thread.currentThread().getName()+" "+msg); - } - - - class ReaderThread extends Thread { - int tNum; - VerifierThread vt; - - ReaderThread(int i, VerifierThread vt) { - super("R-" + i); - tNum = i; - this.vt = vt; - } - - public void run() { - printMessage("In run()"); - - for (int t = 0; t < RLOOP; t++) { - if (vt.isClosed()) { - return; - } - - //printMessage("Asking for read lock."); - lock.getReadLock(); - //printMessage("Got read lock."); - printMessage("Value1 is " + value1); - printMessage("Value2 is " + value2); - - delay(10); - - //printMessage("About to release read lock."); - lock.releaseReadLock(); - } - } - } - - class WriterThread extends Thread { - int tNum; - VerifierThread vt; - - WriterThread(int i, VerifierThread vt) { - super("W-" + i); - tNum = i; - this.vt = vt; - } - - public void run() { - printMessage("In run"); - - for (int t = 0; t < WLOOP; t++) { - if (vt.isClosed()) { - return; - } - - // on average, the wait is (3.5)*30 - delay((((tNum * 13) + t) % 7) * 30); - - //printMessage("Asking for write lock."); - lock.getWriteLock(); - //printMessage("Got write lock."); - printMessage("About to increment values."); - value1 += 1; - value2 += 10; - - delay(10); - - //printMessage("About to release write lock."); - lock.releaseWriteLock(); - } - } - } -} diff --git a/tests/src/java/org/apache/log4j/helpers/UtilLoggingLevelTest.java b/tests/src/java/org/apache/log4j/helpers/UtilLoggingLevelTest.java new file mode 100644 index 0000000000..58105ee8c1 --- /dev/null +++ b/tests/src/java/org/apache/log4j/helpers/UtilLoggingLevelTest.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.helpers; + +import junit.framework.*; + + +/** + * Unit tests for UtilLoggingLevel. + */ + +public class UtilLoggingLevelTest extends TestCase { + + /** + * Create new instance of test. + * + * @param testName test name + */ + public UtilLoggingLevelTest(final String testName) { + super(testName); + } + + /** + * Test toLevel("fiNeSt"). + */ + public void testToLevelFINEST() { + assertSame(UtilLoggingLevel.FINEST, UtilLoggingLevel.toLevel("fiNeSt")); + } + +} + diff --git a/tests/src/java/org/apache/log4j/helpers/VerifierThread.java b/tests/src/java/org/apache/log4j/helpers/VerifierThread.java deleted file mode 100644 index bc3b64d4aa..0000000000 --- a/tests/src/java/org/apache/log4j/helpers/VerifierThread.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.helpers; - -import org.apache.oro.text.perl.Perl5Util; - -import java.io.BufferedReader; -import java.io.IOException; - -/** - * This thread knows about the number of reader and writer threads and keeps - * track of their operations. - * - * @author Ceki Gülcü - * - */ -class VerifierThread extends Thread { - int writeLockHolder = -1; - - boolean[] readLockHolders; - boolean[] readLockWaiters; - boolean[] writerLockWaiters; - BufferedReader bufferedReader; - double v1 = 0; - double v2 = 0; - Perl5Util regex; - Exception exception; - boolean closed; - - VerifierThread(BufferedReader br, int numberOfReaders, int numberOfWriters) { - bufferedReader = br; - readLockHolders = new boolean[numberOfReaders]; - readLockWaiters = new boolean[numberOfReaders]; - writerLockWaiters = new boolean[numberOfWriters]; - regex = new Perl5Util(); - } - - boolean isClosed() { - return closed; - } - - public void run() { - System.out.println("In run of VerifThread"); - String line = null; - - while (!closed) { - try { - line = bufferedReader.readLine(); - if(!closed) { - System.out.println(line); - } - if (regex.match("/([RW])-(\\d{1,3}) (.*)/", line)) { - String type = regex.group(1); - int num = Integer.parseInt(regex.group(2)); - String msg = regex.group(3); - - //System.out.println(type +"_"+num+ " "+msg); - if (type.equals("R")) { - readerMsg(num, msg); - } else if (type.equals("W")) { - writerMsg(num, msg); - } - } else { - System.out.println( - "[" + line + "] does not match expected pattern."); - } - } catch(IOException ioe) { - System.err.println("IOException occured."); - ioe.printStackTrace(System.err); - }catch (Exception e) { - if(exception == null) { - exception = e; - } - closed = true; - System.out.println("====Offending line ["+line+"]."); - e.printStackTrace(System.out); - } - } - } - - public Exception getException() { - return exception; - } - - void readerMsg(int num, String msg) { - if (msg.equals("Asking for read lock.")) { - askReadLock(num); - } else if (msg.equals("Got read lock.")) { - gotReadLock(num); - } else if (msg.startsWith("Value1")) { - value1Message(num, msg); - } else if (msg.startsWith("Value2")) { - value2Message(num, msg); - } else if (msg.equals("About to release read lock.")) { - releaseReadLock(num); - } - } - - void writerMsg(int num, String msg) { - if (msg.equals("Asking for write lock.")) { - askWriterLock(num); - } else if (msg.equals("Got write lock.")) { - gotWriteLock(num); - } else if (msg.equals("About to increment values.")) { - v1 += 1; - v2 += 10.0; - } else if (msg.equals("About to release write lock.")) { - releaseWriteLock(num); - } - } - - boolean writerHoldsLock() { - return writeLockHolder != -1; - } - - boolean writerIsWaiting() { - for (int i = 0; i < writerLockWaiters.length; i++) { - if (writerLockWaiters[i]) { - return true; - } - } - - return false; - } - - void askReadLock(int num) { - readLockWaiters[num] = true; - } - - void askWriterLock(int num) { - writerLockWaiters[num] = true; - } - - void gotReadLock(int num) { - if (!readLockWaiters[num]) { - throw new IllegalStateException( - "Reader " + num + " got a lock without asking."); - } - - if (writerHoldsLock()) { - throw new IllegalStateException( - "Reader " + num + " got a lock while a writer had it."); - } - - if (writerIsWaiting()) { - throw new IllegalStateException( - "Reader " + num + " got a lock while a writers were waiting."); - } - - readLockWaiters[num] = false; - readLockHolders[num] = true; - } - - void gotWriteLock(int num) { - if (!writerLockWaiters[num]) { - throw new IllegalStateException( - "Writer " + num + " got a lock without asking."); - } - - if (writerHoldsLock()) { - throw new IllegalStateException( - "Writer " + num + " got a lock while a writer had it."); - } - - writerLockWaiters[num] = false; - writeLockHolder = num; - } - - void releaseReadLock(int num) { - if (readLockWaiters[num]) { - throw new IllegalStateException( - "Reader " + num + " released a lock while waiting for it."); - } - - if (writerHoldsLock()) { - throw new IllegalStateException( - "Reader " + num + " released a lock while a writer had it."); - } - - readLockHolders[num] = false; - } - - void releaseWriteLock(int num) { - if (writerLockWaiters[num]) { - throw new IllegalStateException( - "Writer " + num + " released a lock while waiting for it."); - } - - writeLockHolder = -1; - } - - void value1Message(int num, String msg) { - if (regex.match("/Value1 is (\\d*)/", msg)) { - double r = Double.parseDouble(regex.group(1)); - - if (r != v1) { - throw new IllegalStateException( - "Reported value is " + r + " was expecting " + v1); - } - } - } - - void value2Message(int num, String msg) { - if (regex.match("/Value1 is (\\d*)/", msg)) { - double r = Double.parseDouble(regex.group(1)); - - if (r != v2) { - throw new IllegalStateException( - "Reported value is " + r + " was expecting " + v2); - } - } - } -} diff --git a/tests/src/java/org/apache/log4j/html/Loop.java b/tests/src/java/org/apache/log4j/html/Loop.java deleted file mode 100644 index 5935af33b6..0000000000 --- a/tests/src/java/org/apache/log4j/html/Loop.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.log4j.html; - -import org.apache.log4j.FileAppender; -import org.apache.log4j.Logger; -import org.apache.log4j.HTMLLayout; - -import java.util.Random; - - -/** - * Tests HTML layout. - * @author Ceki - */ -public class Loop { - public static final Logger logger = Logger.getLogger(Loop.class); - - public static void main(String[] args) { - HTMLLayout htmlLayout = new HTMLLayout("%sn%date%thread%level%logger%m"); - //htmlLayout.setInternalCSS(true); - //EnhancedHTMLLayout htmlLayout = new EnhancedHTMLLayout("%relative%thread%level%logger%m"); - FileAppender appender = new FileAppender(); - appender.setFile("toto.html"); - appender.setAppend(false); - appender.setLayout(htmlLayout); - appender.activateOptions(); - Logger root = Logger.getRootLogger(); - root.addAppender(appender); - - loop(200); - appender.close(); - } - - static void loop(int len) { - Random random = new Random(); - for (int i = 0; i < len; i++) { - int r = random.nextInt(200); - if (r < 150) { - logger.debug("message "+i); - } else if (r < 180) { - logger.info("some veryyyyyyyyyy loooooooooooooong informational message. Blah blah bla. Blah blah blah. " + i); - } else if (r < 190) { - logger.warn("some warning message " + i); - } else { - logger.error("some error message " + i, new Exception("testing")); - } - } - } -} diff --git a/tests/src/java/org/apache/log4j/jmx/HierarchyMBeanTest.java b/tests/src/java/org/apache/log4j/jmx/HierarchyMBeanTest.java deleted file mode 100644 index 2a3711897e..0000000000 --- a/tests/src/java/org/apache/log4j/jmx/HierarchyMBeanTest.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.apache.log4j.jmx; - -import java.util.Iterator; -import java.util.Properties; -import java.util.Set; -import java.util.TreeSet; - -import javax.management.MBeanParameterInfo; -import javax.management.MBeanServer; -import javax.management.MBeanServerFactory; -import javax.management.ObjectName; - -import junit.framework.TestCase; - -import org.apache.log4j.Logger; -import org.apache.log4j.PropertyConfigurator; -import org.apache.log4j.varia.NullAppender; - -public class HierarchyMBeanTest extends TestCase { - - public void testConf() throws Exception { - Properties p = new Properties(); - p.put("log4j.rootLogger","DEBUG,C"); - p.put("log4j.appender.C","org.apache.log4j.ConsoleAppender"); - p.put("log4j.appender.C","layout=org.apache.log4j.SimpleLayout"); - PropertyConfigurator.configure(p); - HierarchyDynamicMBean h = new HierarchyDynamicMBean(); - - Logger l = Logger.getLogger(getClass()); - l.info("hi"); - - MBeanServer server = MBeanServerFactory.createMBeanServer(); - ObjectName ho = new ObjectName("foo:type=Hierarchy"); - server.registerMBean(h, ho); - assertTrue(server.isRegistered(new ObjectName("foo:logger=root"))); - - NullAppender a = new NullAppender(); - a.setName("na"); - l.addAppender(a); - // Use MBeanServer ... - // h.addLoggerMBean(l); - server.invoke(ho, "addLoggerMBean", new Object[] { l.getName() }, null); - assertTrue(server.isRegistered(new ObjectName("foo:logger=" + l.getName()))); - assertTrue(server.isRegistered(new ObjectName("foo:appender=na"))); - - server.invoke(ho, "addLoggerMBeans", null, null); - - Set set = server.queryNames(null, null); - Iterator i = set.iterator(); - while (i.hasNext()) - System.out.println(i.next()); - } - - public void testInfo() { - // Some JMX implementations do not allow spaces in parameter names - MBeanParameterInfo info = new MBeanParameterInfo("spa ce", TestCase.class.toString(), "desc"); - } - -} diff --git a/tests/src/java/org/apache/log4j/joran/InterpreterTest.java b/tests/src/java/org/apache/log4j/joran/InterpreterTest.java deleted file mode 100644 index 9921ff5e5d..0000000000 --- a/tests/src/java/org/apache/log4j/joran/InterpreterTest.java +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Created on Aug 24, 2003 - * - * To change the template for this generated file go to - * Window>Preferences>Java>Code Generation>Code and Comments - */ -package org.apache.log4j.joran; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.apache.log4j.joran.action.NestComponentIA; - -import org.apache.log4j.Appender; -import org.apache.log4j.ConsoleAppender; -import org.apache.log4j.FileAppender; -import org.apache.log4j.Level; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.PatternLayout; -import org.apache.log4j.joran.action.ActionConst; -import org.apache.log4j.joran.action.AppenderAction; -import org.apache.log4j.joran.action.AppenderRefAction; -import org.apache.log4j.joran.action.ConversionRuleAction; -import org.apache.log4j.joran.action.LayoutAction; -import org.apache.log4j.joran.action.LevelAction; -import org.apache.log4j.joran.action.LoggerAction; -import org.apache.log4j.joran.action.NewRuleAction; -import org.apache.log4j.joran.action.ParamAction; -import org.apache.log4j.joran.action.RootLoggerAction; -import org.apache.log4j.joran.action.StackCounterAction; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.joran.spi.Interpreter; -import org.apache.log4j.joran.spi.Pattern; -import org.apache.log4j.joran.spi.RuleStore; -import org.apache.log4j.joran.spi.SimpleRuleStore; -import org.apache.log4j.rolling.RollingFileAppender; -import org.apache.log4j.rolling.SizeBasedTriggeringPolicy; -import org.apache.log4j.rolling.FixedWindowRollingPolicy; -import org.apache.log4j.spi.ErrorItem; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggerRepositoryEx; -import org.xml.sax.SAXParseException; - -import java.util.HashMap; -import java.util.Map; -import java.util.Stack; - -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - - -/** - * @author ceki - * - * To change the template for this generated type comment go to - * Window>Preferences>Java>Code Generation>Code and Comments - */ -public class InterpreterTest extends TestCase { - static final Logger logger = Logger.getLogger(InterpreterTest.class); - - /** - * Constructor for JoranParserTestCase. - * @param name - */ - public InterpreterTest(String name) { - super(name); - } - - /* - * @see TestCase#setUp() - */ - protected void setUp() throws Exception { - super.setUp(); - - Logger root = Logger.getRootLogger(); - root.addAppender( - new ConsoleAppender(new PatternLayout("%r %5p [%t] %c - %m%n"))); - - } - - /* - * @see TestCase#tearDown() - */ - protected void tearDown() throws Exception { - super.tearDown(); - LogManager.shutdown(); - } - - SAXParser createParser() throws Exception { - SAXParserFactory spf = SAXParserFactory.newInstance(); - return spf.newSAXParser(); - } - - public void testIllFormedXML() throws Exception { - RuleStore rs = new SimpleRuleStore(); - - Interpreter jp = new Interpreter(rs); - ExecutionContext ec = jp.getExecutionContext(); - SAXParser saxParser = createParser(); - try { - saxParser.parse("file:input/joran/illFormed.xml", jp); - fail("A parser exception should have occured"); - } catch(SAXParseException e) { - assertEquals(1, ec.getErrorList().size()); - ErrorItem e0 = (ErrorItem) ec.getErrorList().get(0); - String e0msg = e0.getMessage(); - if(!e0msg.startsWith("Parsing fatal error")) { - fail("Expected error string [Parsing fatal error] but got ["+e0msg+"]"); - } - - } - } - - /** - * Tests the basic looping contruct in Interpreter. - * - * The parser is set up to push 2 string objects for each element encountered. - * The results are compared with a witness stack. - */ - public void testBasicLoop() throws Exception { - - RuleStore rs = new SimpleRuleStore(); - rs.addRule( - new Pattern("log4j:configuration"), new StackCounterAction()); - rs.addRule( - new Pattern("log4j:configuration/root"), new StackCounterAction()); - rs.addRule( - new Pattern("log4j:configuration/root/level"), new StackCounterAction()); - - Interpreter jp = new Interpreter(rs); - ExecutionContext ec = jp.getExecutionContext(); - SAXParser saxParser = createParser(); - saxParser.parse("file:input/joran/basicLoop.xml", jp); - - Stack witness = new Stack(); - witness.push("log4j:configuration-begin"); - witness.push("root-begin"); - witness.push("level-begin"); - witness.push("level-end"); - witness.push("root-end"); - witness.push("log4j:configuration-end"); - assertEquals(witness, ec.getObjectStack()); - } - - /** - * This test verifies that , and embedded elements - * are handled correctly. - */ - public void testParsing1() throws Exception { - logger.debug("Starting testLoop"); - - RuleStore rs = new SimpleRuleStore(); - - rs.addRule(new Pattern("log4j:configuration"), new NOPAction()); - rs.addRule(new Pattern("log4j:configuration/logger"), new LoggerAction()); - rs.addRule(new Pattern("*/appender-ref"), new NOPAction()); - rs.addRule( - new Pattern("log4j:configuration/logger/level"), new LevelAction()); - rs.addRule( - new Pattern("log4j:configuration/root"), new RootLoggerAction()); - rs.addRule( - new Pattern("log4j:configuration/root/level"), new LevelAction()); - - Interpreter jp = new Interpreter(rs); - ExecutionContext ec = jp.getExecutionContext(); - Map omap = ec.getObjectMap(); - omap.put(ActionConst.APPENDER_BAG, new HashMap()); - ec.pushObject(LogManager.getLoggerRepository()); - SAXParser saxParser = createParser(); - saxParser.parse("file:input/joran/parser1.xml", jp); - - Logger rootLogger = LogManager.getLoggerRepository().getRootLogger(); - assertSame(Level.WARN, rootLogger.getLevel()); - - Logger asdLogger = LogManager.getLoggerRepository().getLogger("asd"); - assertSame(Level.DEBUG, asdLogger.getLevel()); - - assertEquals(2, ec.getErrorList().size()); - ErrorItem e0 = (ErrorItem) ec.getErrorList().get(0); - if(!e0.getMessage().startsWith("No 'name' attribute in element")) { - fail("Expected error string [No 'name' attribute in element]"); - } - ErrorItem e1 = (ErrorItem) ec.getErrorList().get(1); - if(!e1.getMessage().startsWith("For element ")) { - fail("Expected error string [For element ]"); - } - } - - /** - * This tests verifies the handling of logger, logger/level, root, root/level - * logger/appender-ref, root/appender-ref, appender, appender/layout, - * and param actions. - * - * These cover a fairly significant part of log4j configuration directives. - * - * */ - public void testParsing2() throws Exception { - logger.debug("Starting testLoop2"); - RuleStore rs = new SimpleRuleStore(); - rs.addRule(new Pattern("log4j:configuration"), new NOPAction()); - rs.addRule(new Pattern("log4j:configuration/logger"), new LoggerAction()); - rs.addRule( - new Pattern("log4j:configuration/logger/level"), new LevelAction()); - rs.addRule( - new Pattern("log4j:configuration/root"), new RootLoggerAction()); - rs.addRule( - new Pattern("log4j:configuration/root/level"), new LevelAction()); - rs.addRule( - new Pattern("log4j:configuration/logger/appender-ref"), - new AppenderRefAction()); - rs.addRule( - new Pattern("log4j:configuration/root/appender-ref"), - new AppenderRefAction()); - rs.addRule( - new Pattern("log4j:configuration/appender"), new AppenderAction()); - rs.addRule( - new Pattern("log4j:configuration/appender/layout"), new LayoutAction()); - rs.addRule(new Pattern("*/param"), new ParamAction()); - - Interpreter jp = new Interpreter(rs); - ExecutionContext ec = jp.getExecutionContext(); - Map omap = ec.getObjectMap(); - omap.put(ActionConst.APPENDER_BAG, new HashMap()); - ec.pushObject(LogManager.getLoggerRepository()); - SAXParser saxParser = createParser(); - saxParser.parse("file:input/joran/parser2.xml", jp); - - // the following assertions depend on the contensts of parser2.xml - Logger rootLogger = LogManager.getLoggerRepository().getRootLogger(); - assertSame(Level.DEBUG, rootLogger.getLevel()); - - Logger asdLogger = LogManager.getLoggerRepository().getLogger("asd"); - assertSame(Level.INFO, asdLogger.getLevel()); - - FileAppender a1Back = (FileAppender) asdLogger.getAppender("A1"); - assertFalse("a1.append should be false", a1Back.getAppend()); - assertEquals("output/temp.A1", a1Back.getFile()); - PatternLayout plBack = (PatternLayout) a1Back.getLayout(); - assertEquals("%-5p %c{2} - %m%n", plBack.getConversionPattern()); - - a1Back = (FileAppender) rootLogger.getAppender("A1"); - - assertEquals(3, ec.getErrorList().size()); - ErrorItem e0 = (ErrorItem) ec.getErrorList().get(0); - if(!e0.getMessage().startsWith("No 'name' attribute in element")) { - fail("Expected error string [No 'name' attribute in element]"); - } - ErrorItem e1 = (ErrorItem) ec.getErrorList().get(1); - if(!e1.getMessage().startsWith("For element ")) { - fail("Expected error string [For element ]"); - } - ErrorItem e2 = (ErrorItem) ec.getErrorList().get(2); - if(!e2.getMessage().startsWith("Could not find an AppenderAttachable at the top of execution stack. Near")) { - fail("Expected error string [Could not find an AppenderAttachable at the top of execution stack. Near]"); - } - - } - - public void testParsing3() throws Exception { - logger.debug("Starting testLoop3"); - - RuleStore rs = new SimpleRuleStore(); - rs.addRule(new Pattern("log4j:configuration/logger"), new LoggerAction()); - rs.addRule( - new Pattern("log4j:configuration/logger/level"), new LevelAction()); - rs.addRule( - new Pattern("log4j:configuration/root"), new RootLoggerAction()); - rs.addRule( - new Pattern("log4j:configuration/root/level"), new LevelAction()); - rs.addRule( - new Pattern("log4j:configuration/logger/appender-ref"), - new AppenderRefAction()); - rs.addRule( - new Pattern("log4j:configuration/root/appender-ref"), - new AppenderRefAction()); - rs.addRule( - new Pattern("log4j:configuration/appender"), new AppenderAction()); - rs.addRule( - new Pattern("log4j:configuration/appender/layout"), new LayoutAction()); - rs.addRule(new Pattern("*/param"), new ParamAction()); - - Interpreter jp = new Interpreter(rs); - jp.addImplicitAction(new NestComponentIA()); - - ExecutionContext ec = jp.getExecutionContext(); - Map omap = ec.getObjectMap(); - omap.put(ActionConst.APPENDER_BAG, new HashMap()); - ec.pushObject(LogManager.getLoggerRepository()); - logger.debug("About to parse doc"); - - SAXParser saxParser = createParser(); - saxParser.parse("file:input/joran/parser3.xml", jp); - - // the following assertions depend on the contensts of parser3.xml - Logger rootLogger = LogManager.getLoggerRepository().getRootLogger(); - assertSame(Level.WARN, rootLogger.getLevel()); - - RollingFileAppender a1Back = (RollingFileAppender) rootLogger.getAppender("A1"); - assertFalse("a1.append should be false", a1Back.getAppend()); - PatternLayout plBack = (PatternLayout) a1Back.getLayout(); - assertEquals("%-5p %c{2} - %m%n", plBack.getConversionPattern()); - - FixedWindowRollingPolicy swrp = (FixedWindowRollingPolicy) a1Back.getRollingPolicy(); - assertEquals("output/parser3", swrp.getActiveFileName()); - assertEquals("output/parser3.%i", swrp.getFileNamePattern()); - - SizeBasedTriggeringPolicy sbtp = (SizeBasedTriggeringPolicy) a1Back.getTriggeringPolicy(); - assertEquals(100, sbtp.getMaxFileSize()); - - //System.out.println(ec.getErrorList()); - } - - public void testNewConversionWord() throws Exception { - logger.debug("Starting testNewConversionWord"); - - RuleStore rs = new SimpleRuleStore(); - rs.addRule( - new Pattern("configuration/appender"), new AppenderAction()); - rs.addRule( - new Pattern("configuration/appender/layout"), new LayoutAction()); - rs.addRule( - new Pattern("configuration/conversionRule"), - new ConversionRuleAction()); - - rs.addRule(new Pattern("*/param"), new ParamAction()); - - Interpreter jp = new Interpreter(rs); - jp.addImplicitAction(new NestComponentIA()); - - ExecutionContext ec = jp.getExecutionContext(); - Map omap = ec.getObjectMap(); - omap.put(ActionConst.APPENDER_BAG, new HashMap()); - LoggerRepository repository = LogManager.getLoggerRepository(); - ec.pushObject(repository); - - SAXParser saxParser = createParser(); - saxParser.parse("file:input/joran/conversionRule.xml", jp); - - HashMap appenderBag = - (HashMap) ec.getObjectMap().get(ActionConst.APPENDER_BAG); - Appender appender = (Appender) appenderBag.get("A1"); - PatternLayout pl = (PatternLayout) appender.getLayout(); - - Map ruleRegistry = (Map) ((LoggerRepositoryEx) repository).getObject(PatternLayout.PATTERN_RULE_REGISTRY); - assertEquals("org.apache.log4j.toto", ruleRegistry.get("toto")); - } - - - - - public void testNewRule1() throws Exception { - logger.debug("Starting testNewConversionWord"); - - RuleStore rs = new SimpleRuleStore(); - rs.addRule( - new Pattern("log4j:configuration/newRule"), - new NewRuleAction()); - - Interpreter jp = new Interpreter(rs); - ExecutionContext ec = jp.getExecutionContext(); - Map omap = ec.getObjectMap(); - - SAXParser saxParser = createParser(); - saxParser.parse("file:input/joran/newRule1.xml", jp); - - String str = (String) ec.getObjectMap().get("hello"); - assertEquals("Hello John Doe.", str); - } - - public static Test RUNALLsuite() { - TestSuite suite = new TestSuite(); - //suite.addTest(new InterpreterTest("testIllFormedXML")); - //suite.addTest(new InterpreterTest("testBasicLoop")); - //suite.addTest(new InterpreterTest("testParsing1")); - //suite.addTest(new InterpreterTest("testParsing2")); - //suite.addTest(new InterpreterTest("testParsing3")) - suite.addTest(new InterpreterTest("testException1")); - suite.addTest(new InterpreterTest("testException2")); - return suite; - } - -} diff --git a/tests/src/java/org/apache/log4j/joran/JoranConfiguratorTest.java b/tests/src/java/org/apache/log4j/joran/JoranConfiguratorTest.java deleted file mode 100644 index c65292bde5..0000000000 --- a/tests/src/java/org/apache/log4j/joran/JoranConfiguratorTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran; - -import java.util.List; - -import org.apache.log4j.Level; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.util.Compare; -import org.apache.log4j.util.ControlFilter; -import org.apache.log4j.util.Filter; -import org.apache.log4j.util.JunitTestRunnerFilter; -import org.apache.log4j.util.LineNumberFilter; -import org.apache.log4j.util.SunReflectFilter; -import org.apache.log4j.util.Transformer; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - - -/** - * Various tests verifying that JoranConfigurator can effectively - * parse config files. - * - * @author Ceki Gulcu - */ -public class JoranConfiguratorTest extends TestCase { - Logger root; - Logger logger; - - public final static String FILTERED = "output/filtered"; - public final static String TEMP = "output/temp"; - - static String TEST1_PAT = "(DEBUG|INFO|WARN|ERROR|FATAL) - Message \\d"; - static String EXCEPTION1 = "java.lang.Exception: Just testing"; - static String EXCEPTION2 = "\\s*at .*\\(.*:\\d{1,4}\\)"; - static String EXCEPTION3 = "\\s*at .*\\(Native Method\\)"; - JoranConfigurator jc = new JoranConfigurator(); - - public JoranConfiguratorTest(String name) { - super(name); - } - - public void setUp() { - root = Logger.getRootLogger(); - logger = Logger.getLogger(JoranConfiguratorTest.class); - } - - public void tearDown() { - root.getLoggerRepository().resetConfiguration(); - } - - - public void test1() { - jc.doConfigure("./input/joran/simple2.xml", LogManager.getLoggerRepository()); - - List errorList = jc.getExecutionContext().getErrorList(); - for(int i = 0; i < errorList.size(); i++) { - System.out.println(errorList.get(i)); - } - } - - public void testResourceBundle() { - jc.doConfigure("./input/joran/resourceBundle.xml", LogManager.getLoggerRepository()); - Logger l = Logger.getLogger("foo"); - assertNotNull(l.getResourceBundle()); - assertNull(Logger.getLogger("bar").getResourceBundle()); - } - - public void testXInclude() { - jc.doConfigure("./input/xml/xinclude.xml", LogManager.getLoggerRepository()); - jc.dumpErrors(); - Logger l = Logger.getLogger("foo"); - assertEquals(Level.INFO, l.getLevel()); - System.out.println(jc.getExecutionContext().getErrorList()); - } - - public void testAsync() throws Exception { - jc.doConfigure("./input/joran/asyncTest.xml", LogManager.getLoggerRepository()); - jc.dumpErrors(); - common(); - - // allow time for the Aync thread to do its job - Thread.sleep(2000); - - ControlFilter cf = new ControlFilter(new String[]{TEST1_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3}); - - - Transformer.transform(TEMP, FILTERED, new Filter[] {cf, - new LineNumberFilter(), - new SunReflectFilter(), - new JunitTestRunnerFilter()}); - - assertTrue(Compare.compare(FILTERED, "witness/joran/async")); - } - - void common() { - int i = -1; - - logger.debug("Message " + ++i); - root.debug("Message " + i); - - logger.info ("Message " + ++i); - root.info("Message " + i); - - logger.warn ("Message " + ++i); - root.warn("Message " + i); - - logger.error("Message " + ++i); - root.error("Message " + i); - - logger.log(Level.FATAL, "Message " + ++i); - root.log(Level.FATAL, "Message " + i); - - Exception e = new Exception("Just testing"); - logger.debug("Message " + ++i, e); - root.debug("Message " + i, e); - - logger.error("Message " + ++i, e); - root.error("Message " + i, e); - } - -} diff --git a/tests/src/java/org/apache/log4j/joran/NOPAction.java b/tests/src/java/org/apache/log4j/joran/NOPAction.java deleted file mode 100644 index feb3dfddc4..0000000000 --- a/tests/src/java/org/apache/log4j/joran/NOPAction.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran; - -import org.apache.log4j.joran.action.Action; -import org.apache.log4j.joran.spi.ExecutionContext; - -import org.xml.sax.Attributes; - - - -/** - * No operation (NOP) action that does strictly nothing. - * - * @author Ceki Gülcü - */ -public class NOPAction extends Action { - - public void begin(ExecutionContext ec, String name, Attributes attributes) { - } - - - public void end(ExecutionContext ec, String name) { - } -} diff --git a/tests/src/java/org/apache/log4j/joran/PatternTest.java b/tests/src/java/org/apache/log4j/joran/PatternTest.java deleted file mode 100644 index 2fbdcefab6..0000000000 --- a/tests/src/java/org/apache/log4j/joran/PatternTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Created on Aug 25, 2003 - * - * To change the template for this generated file go to - * Window>Preferences>Java>Code Generation>Code and Comments - */ -package org.apache.log4j.joran; - - -import org.apache.log4j.joran.spi.Pattern; - -import junit.framework.TestCase; - - -/** - * Test pattern manipulation code. - * - * @author Ceki Gulcu - */ -public class PatternTest extends TestCase { - /** - * Constructor for PatternTestCase. - * @param name - */ - public PatternTest(String name) { - super(name); - } - - /* - * @see TestCase#setUp() - */ - protected void setUp() throws Exception { - super.setUp(); - } - - /* - * @see TestCase#tearDown() - */ - protected void tearDown() throws Exception { - super.tearDown(); - } - - public void test1() { - Pattern p = new Pattern("a"); - assertEquals(1, p.size()); - assertEquals("a", p.peekLast()); - assertEquals("a", p.get(0)); - } - - public void test2() { - Pattern p = new Pattern("a/b"); - assertEquals(2, p.size()); - assertEquals("b", p.peekLast()); - assertEquals("a", p.get(0)); - assertEquals("b", p.get(1)); - } - - public void test3() { - Pattern p = new Pattern("a123/b1234/cvvsdf"); - assertEquals(3, p.size()); - assertEquals("a123", p.get(0)); - assertEquals("b1234", p.get(1)); - assertEquals("cvvsdf", p.get(2)); - } - - public void test4() { - Pattern p = new Pattern("/a123/b1234/cvvsdf"); - assertEquals(3, p.size()); - assertEquals("a123", p.get(0)); - assertEquals("b1234", p.get(1)); - assertEquals("cvvsdf", p.get(2)); - } - - public void test5() { - Pattern p = new Pattern("//a"); - assertEquals(1, p.size()); - assertEquals("a", p.get(0)); - } - - public void test6() { - Pattern p = new Pattern("//a//b"); - assertEquals(2, p.size()); - assertEquals("a", p.get(0)); - assertEquals("b", p.get(1)); - } - - -} diff --git a/tests/src/java/org/apache/log4j/joran/SimpleStoreTest.java b/tests/src/java/org/apache/log4j/joran/SimpleStoreTest.java deleted file mode 100644 index 9048859584..0000000000 --- a/tests/src/java/org/apache/log4j/joran/SimpleStoreTest.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Created on Aug 25, 2003 - * - * To change the template for this generated file go to - * Window>Preferences>Java>Code Generation>Code and Comments - */ -package org.apache.log4j.joran; - -import org.apache.log4j.joran.action.Action; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.joran.spi.Pattern; -import org.apache.log4j.joran.spi.SimpleRuleStore; - -import junit.framework.TestCase; - -import org.w3c.dom.Document; -import org.xml.sax.Attributes; -import java.util.List; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - - -/** - * - * @author Ceki Gulcu - * - */ -public class SimpleStoreTest extends TestCase { - /** - * Constructor for SimpleStoreTestCase. - * @param name - */ - public SimpleStoreTest(String name) { - super(name); - } - - /* - * @see TestCase#setUp() - */ - protected void setUp() throws Exception { - super.setUp(); - } - - /* - * @see TestCase#tearDown() - */ - protected void tearDown() throws Exception { - super.tearDown(); - } - - public void test1() throws Exception { - //Document doc = getW3Document("file:input/joran/parser1.xml"); - SimpleRuleStore srs = new SimpleRuleStore(); - srs.addRule(new Pattern("a/b"), new XAction()); - - List r = srs.matchActions(new Pattern("a/b")); - assertNotNull(r); - assertEquals(1, r.size()); - - if (!(r.get(0) instanceof XAction)) { - fail("Wring type"); - } - - srs = new SimpleRuleStore(); - srs.addRule(new Pattern("a/b"), new XAction()); - srs.addRule(new Pattern("a/b"), new YAction()); - - r = srs.matchActions(new Pattern("a/b")); - assertNotNull(r); - assertEquals(2, r.size()); - - if (!(r.get(0) instanceof XAction)) { - fail("Wrong type"); - } - - if (!(r.get(1) instanceof YAction)) { - fail("Wrong type"); - } - - //jp.parse(doc); - } - - public void test2() throws Exception { - SimpleRuleStore srs = new SimpleRuleStore(); - srs.addRule(new Pattern("*/b"), new XAction()); - - List r = srs.matchActions(new Pattern("a/b")); - assertNotNull(r); - - //System.out.println(r); - assertEquals(1, r.size()); - - if (!(r.get(0) instanceof XAction)) { - fail("Wring type"); - } - } - - public void test3() throws Exception { - SimpleRuleStore srs = new SimpleRuleStore(); - srs.addRule(new Pattern("*/b"), new XAction()); - srs.addRule(new Pattern("*/a/b"), new YAction()); - - List r = srs.matchActions(new Pattern("a/b")); - assertNotNull(r); - - //System.out.println("restulg list is: "+r); - assertEquals(1, r.size()); - - if (!(r.get(0) instanceof YAction)) { - fail("Wring type"); - } - } - - public void test4() throws Exception { - SimpleRuleStore srs = new SimpleRuleStore(); - srs.addRule(new Pattern("*/b"), new XAction()); - srs.addRule(new Pattern("*/a/b"), new YAction()); - srs.addRule(new Pattern("a/b"), new ZAction()); - - List r = srs.matchActions(new Pattern("a/b")); - assertNotNull(r); - - //System.out.println("restulg list is: "+r); - assertEquals(1, r.size()); - - if (!(r.get(0) instanceof ZAction)) { - fail("Wring type"); - } - } - - Document getW3Document(String file) throws Exception { - DocumentBuilderFactory dbf = null; - dbf = DocumentBuilderFactory.newInstance(); - - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - - //inputSource.setSystemId("dummy://log4j.dtd"); - return docBuilder.parse(file); - } - - class XAction extends Action { - public void begin(ExecutionContext ec, String name, Attributes attributes) { - } - - public void end(ExecutionContext ec, String name) { - } - - public void finish(ExecutionContext ec) { - } - } - - class YAction extends Action { - public void begin(ExecutionContext ec, String name, Attributes attributes) { - } - - public void end(ExecutionContext ec, String name) { - } - - public void finish(ExecutionContext ec) { - } } - - class ZAction extends Action { - public void begin(ExecutionContext ec, String name, Attributes attributes) { - } - - public void end(ExecutionContext ec, String name) { - } - - public void finish(ExecutionContext ec) { - } } -} diff --git a/tests/src/java/org/apache/log4j/joran/SkippingInInterpreterTest.java b/tests/src/java/org/apache/log4j/joran/SkippingInInterpreterTest.java deleted file mode 100644 index df9d9a50c9..0000000000 --- a/tests/src/java/org/apache/log4j/joran/SkippingInInterpreterTest.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.apache.log4j.ConsoleAppender; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.PatternLayout; -import org.apache.log4j.joran.action.BadBeginAction; -import org.apache.log4j.joran.action.BadEndAction; -import org.apache.log4j.joran.action.HelloAction; -import org.apache.log4j.joran.action.TouchAction; -import org.apache.log4j.joran.spi.ExecutionContext; -import org.apache.log4j.joran.spi.Interpreter; -import org.apache.log4j.joran.spi.Pattern; -import org.apache.log4j.joran.spi.RuleStore; -import org.apache.log4j.joran.spi.SimpleRuleStore; -import org.apache.log4j.spi.ErrorItem; - -import java.util.List; -import java.util.Map; - -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - - -/** - * Test the way Interpreter skips elements in case of exceptions thrown by - * Actions. - * - * @author Ceki Gulcu - */ -public class SkippingInInterpreterTest extends TestCase { - static final Logger logger = Logger.getLogger(SkippingInInterpreterTest.class); - - public SkippingInInterpreterTest(String name) { - super(name); - } - - /* - * @see TestCase#setUp() - */ - protected void setUp() throws Exception { - super.setUp(); - - Logger root = Logger.getRootLogger(); - root.addAppender( - new ConsoleAppender(new PatternLayout("%r %5p [%t] %c - %m%n"))); - - } - - /* - * @see TestCase#tearDown() - */ - protected void tearDown() throws Exception { - super.tearDown(); - LogManager.shutdown(); - } - - SAXParser createParser() throws Exception { - SAXParserFactory spf = SAXParserFactory.newInstance(); - return spf.newSAXParser(); - } - - public void testChildrenSkipping() throws Exception { - logger.debug("Starting testException1"); - - RuleStore rs = new SimpleRuleStore(); - rs.addRule(new Pattern("test"), new NOPAction()); - rs.addRule(new Pattern("test/badBegin"), new BadBeginAction()); - rs.addRule(new Pattern("test/badBegin/touch"), new TouchAction()); - rs.addRule(new Pattern("test/hello"), new HelloAction()); - - Interpreter jp = new Interpreter(rs); - ExecutionContext ec = jp.getExecutionContext(); - Map omap = ec.getObjectMap(); - - SAXParser saxParser = createParser(); - saxParser.parse("file:input/joran/exception1.xml", jp); - List el = jp.getExecutionContext().getErrorList(); - for(int i = 0; i < el.size(); i++) { - ((ErrorItem) el.get(i)).dump(); - } - String str = (String) ec.getObjectMap().get("hello"); - assertEquals("Hello John Doe.", str); - - Integer i = (Integer) ec.getObjectMap().get(TouchAction.KEY); - assertNull(i); - } - - public void testSkipSiblings() throws Exception { - logger.debug("Starting testException2"); - - RuleStore rs = new SimpleRuleStore(); - rs.addRule(new Pattern("test"), new NOPAction()); - rs.addRule(new Pattern("test/badEnd"), new BadEndAction()); - rs.addRule(new Pattern("test/badEnd/touch"), new TouchAction()); - rs.addRule(new Pattern("test/hello"), new HelloAction()); - - Interpreter jp = new Interpreter(rs); - ExecutionContext ec = jp.getExecutionContext(); - Map omap = ec.getObjectMap(); - - SAXParser saxParser = createParser(); - saxParser.parse("file:input/joran/badEnd1.xml", jp); - String str = (String) ec.getObjectMap().get("hello"); - assertNull(str); - Integer i = (Integer) ec.getObjectMap().get(TouchAction.KEY); - assertEquals(2, i.intValue()); - } - - public void testSkipSiblings2() throws Exception { - logger.debug("Starting testException2"); - - RuleStore rs = new SimpleRuleStore(); - rs.addRule(new Pattern("test"), new NOPAction()); - rs.addRule(new Pattern("test/badEnd"), new BadEndAction()); - rs.addRule(new Pattern("test/badEnd/touch"), new TouchAction()); - rs.addRule(new Pattern("test/hello"), new HelloAction()); - - Interpreter jp = new Interpreter(rs); - ExecutionContext ec = jp.getExecutionContext(); - Map omap = ec.getObjectMap(); - - SAXParser saxParser = createParser(); - saxParser.parse("file:input/joran/badEnd2.xml", jp); - - String str = (String) ec.getObjectMap().get("hello"); - assertEquals("Hello John Doe.", str); - Integer i = (Integer) ec.getObjectMap().get(TouchAction.KEY); - assertNull(i); - } - - public static Test RUNALLsuite() { - TestSuite suite = new TestSuite(); - suite.addTest(new SkippingInInterpreterTest("testChildrenSkipping")); - suite.addTest(new SkippingInInterpreterTest("testNoSkipping")); - return suite; - } - -} diff --git a/tests/src/java/org/apache/log4j/joran/action/BadBeginAction.java b/tests/src/java/org/apache/log4j/joran/action/BadBeginAction.java deleted file mode 100644 index 0a9e67394d..0000000000 --- a/tests/src/java/org/apache/log4j/joran/action/BadBeginAction.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - -import org.apache.log4j.joran.action.Action; -import org.apache.log4j.joran.spi.ExecutionContext; - -import org.xml.sax.Attributes; - - -public class BadBeginAction extends Action { - - - public BadBeginAction() { - } - - public void begin(ExecutionContext ec, String name, Attributes attributes) { - throw new IllegalStateException("bad begin"); - } - - public void end(ExecutionContext ec, String name) { - } -} diff --git a/tests/src/java/org/apache/log4j/joran/action/BadEndAction.java b/tests/src/java/org/apache/log4j/joran/action/BadEndAction.java deleted file mode 100644 index 3975037969..0000000000 --- a/tests/src/java/org/apache/log4j/joran/action/BadEndAction.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - -import org.apache.log4j.joran.action.Action; -import org.apache.log4j.joran.spi.ExecutionContext; - -import org.xml.sax.Attributes; - - -public class BadEndAction extends Action { - - - public void begin(ExecutionContext ec, String name, Attributes attributes) { - } - - public void end(ExecutionContext ec, String name) { - throw new IllegalStateException("bad end"); - } -} diff --git a/tests/src/java/org/apache/log4j/joran/action/HelloAction.java b/tests/src/java/org/apache/log4j/joran/action/HelloAction.java deleted file mode 100644 index 00b79d3d3d..0000000000 --- a/tests/src/java/org/apache/log4j/joran/action/HelloAction.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - -import org.apache.log4j.joran.action.Action; -import org.apache.log4j.joran.spi.ExecutionContext; - -import org.xml.sax.Attributes; - - -public class HelloAction extends Action { - - - public HelloAction() { - } - /** - * Instantiates an layout of the given class and sets its name. - * - */ - public void begin(ExecutionContext ec, String name, Attributes attributes) { - String str = "Hello "+attributes.getValue("name")+"."; - ec.getObjectMap().put("hello", str); - } - - /** - * Once the children elements are also parsed, now is the time to activate - * the appender options. - */ - public void end(ExecutionContext ec, String name) { - } -} diff --git a/tests/src/java/org/apache/log4j/joran/action/StackCounterAction.java b/tests/src/java/org/apache/log4j/joran/action/StackCounterAction.java deleted file mode 100644 index cc8ed869be..0000000000 --- a/tests/src/java/org/apache/log4j/joran/action/StackCounterAction.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - -import org.apache.log4j.joran.action.Action; -import org.apache.log4j.joran.spi.ExecutionContext; - -import org.xml.sax.Attributes; - -public class StackCounterAction extends Action { - - public StackCounterAction() { - } - - public void begin(ExecutionContext ec, String name, Attributes attributes) { - ec.pushObject(name+"-begin"); - } - - public void end(ExecutionContext ec, String name) { - ec.pushObject(name+"-end"); - } - - public void finish(ExecutionContext ec) { - } -} diff --git a/tests/src/java/org/apache/log4j/joran/action/TouchAction.java b/tests/src/java/org/apache/log4j/joran/action/TouchAction.java deleted file mode 100644 index ea5def0977..0000000000 --- a/tests/src/java/org/apache/log4j/joran/action/TouchAction.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.joran.action; - -import org.apache.log4j.joran.action.Action; -import org.apache.log4j.joran.spi.ExecutionContext; - -import org.xml.sax.Attributes; - - -public class TouchAction extends Action { - - public static final String KEY = "touched"; - - public TouchAction() { - } - /** - * Instantiates an layout of the given class and sets its name. - * - */ - public void begin(ExecutionContext ec, String name, Attributes attributes) { - - Integer i = (Integer) ec.getObjectMap().get(KEY); - if(i == null) { - ec.getObjectMap().put(KEY, new Integer(1)); - } else { - ec.getObjectMap().put(KEY, new Integer(i.intValue()+1)); - } - } - - /** - * Once the children elements are also parsed, now is the time to activate - * the appender options. - */ - public void end(ExecutionContext ec, String name) { - } -} diff --git a/tests/src/java/org/apache/log4j/lbel/CoreParserTest.java b/tests/src/java/org/apache/log4j/lbel/CoreParserTest.java deleted file mode 100644 index dd3c2e3ea6..0000000000 --- a/tests/src/java/org/apache/log4j/lbel/CoreParserTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.lbel; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import java.io.IOException; - -/* - * Verify that the parser can handle the core language correctly. - * - * @author Ceki Gülcü - */ -public class CoreParserTest extends TestCase { - LBELEventEvaluator evaluator; - - public CoreParserTest(String arg0) { - super(arg0); - } - - protected void setUp() throws Exception { - super.setUp(); - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - - public void testTrue() throws ScanError { - evaluator = new LBELEventEvaluator("true"); - assertTrue(evaluator.evaluate(null)); - } - - public void testTrueOrFalse() throws ScanError { - evaluator = new LBELEventEvaluator("true OR false"); - assertTrue(evaluator.evaluate(null)); - } - - public void testNotTrue() throws ScanError { - evaluator = new LBELEventEvaluator("not true"); - assertTrue(!evaluator.evaluate( null)); - } - - public void testAndOr() throws ScanError { - evaluator = new LBELEventEvaluator("true or false and true"); - assertTrue(evaluator.evaluate( null)); - } - - public void testAndOr2() throws ScanError { - evaluator = new LBELEventEvaluator("false or false and true"); - assertTrue(!evaluator.evaluate(null)); - } - - public void testAndOr3() throws ScanError { - evaluator = new LBELEventEvaluator("false or true and true"); - assertTrue(evaluator.evaluate( null)); - } - - public void testParatheses() throws ScanError { - evaluator = new LBELEventEvaluator("(true or false)"); - assertTrue(evaluator.evaluate( null)); - } - - public void testParatheses2() throws ScanError { - evaluator = new LBELEventEvaluator("(not (true or false)) and true"); - assertTrue(!evaluator.evaluate( null)); - } - - public void testNotPrecedence() throws IOException, ScanError { - evaluator = new LBELEventEvaluator("not true or false and true"); - assertTrue(!evaluator.evaluate( null)); - } - - public void testNotPrecedence2() throws IOException, ScanError { - evaluator = new LBELEventEvaluator("not true or true and true"); - assertTrue(evaluator.evaluate( null)); - } - - public void testNotPrecedence3() throws IOException, ScanError { - evaluator = new LBELEventEvaluator("not true and true or false"); - assertTrue(!evaluator.evaluate( null)); - } - - public void testNotPrecedence4() throws IOException, ScanError { - evaluator = new LBELEventEvaluator("not true and true or false"); - assertTrue(!evaluator.evaluate( null)); - } - - - public static Test XXsuite() { - TestSuite suite = new TestSuite(); - //suite.addTest(new ParserTest("testAndOr")); - suite.addTest(new CoreParserTest("testTrue")); - return suite; - } - -} diff --git a/tests/src/java/org/apache/log4j/lbel/CountingReader.java b/tests/src/java/org/apache/log4j/lbel/CountingReader.java deleted file mode 100644 index a1abdf5c5b..0000000000 --- a/tests/src/java/org/apache/log4j/lbel/CountingReader.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Created on Feb 2, 2005 - * - * To change the template for this generated file go to - * Window>Preferences>Java>Code Generation>Code and Comments - */ -package org.apache.log4j.lbel; - -import java.io.IOException; -import java.io.Reader; - - -/** - * Decorate a reader by counting lines and colums. - * - * @author Ceki Gülcü - */ -public class CountingReader extends Reader { - private final Reader reader; - private int lineNumber = 0; - private int columnNumber = 0; - private boolean lastCharacterWasR = false; - - CountingReader(Reader reader) { - this.reader = reader; - } - - public int read() throws IOException { - int r = reader.read(); - if(r != -1) { - switch(r) { - case '\r': - lastCharacterWasR = true; - lineNumber++; - columnNumber = 0; - break; - case '\n': - if(!lastCharacterWasR) { - lineNumber++; - columnNumber = 0; - } - lastCharacterWasR = false; - break; - default: lastCharacterWasR = false; - columnNumber++; - } - } - return r; - } - - public int read(char[] arg0, int arg1, int arg2) throws IOException { - throw new UnsupportedOperationException("char[] reading not supported."); - } - - - public void close() throws IOException { - reader.close(); - } - - public int getColumnNumber() { - return columnNumber; - } - public int getLineNumber() { - return lineNumber; - } -} diff --git a/tests/src/java/org/apache/log4j/lbel/CountingReaderTest.java b/tests/src/java/org/apache/log4j/lbel/CountingReaderTest.java deleted file mode 100644 index 3dcd1e1bf6..0000000000 --- a/tests/src/java/org/apache/log4j/lbel/CountingReaderTest.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.lbel; - -import java.io.IOException; -import java.io.StringReader; - -import junit.framework.TestCase; - - -/** - * - * @author Ceki Gülcü - */ -public class CountingReaderTest extends TestCase { - public CountingReaderTest(String arg0) { - super(arg0); - } - - protected void setUp() throws Exception { - super.setUp(); - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - - public void testOneLiner() throws IOException { - StringReader sr = new StringReader("abc"); - CountingReader cr = new CountingReader(sr); - int c; - c = cr.read(); - assertEquals('a', c); - assertEquals(0, cr.getLineNumber()); - assertEquals(1, cr.getColumnNumber()); - c = cr.read(); - assertEquals('b', c); - assertEquals(0, cr.getLineNumber()); - assertEquals(2, cr.getColumnNumber()); - c = cr.read(); - assertEquals('c', c); - assertEquals(0, cr.getLineNumber()); - assertEquals(3, cr.getColumnNumber()); - - c = cr.read(); - assertEquals(-1, c); - assertEquals(0, cr.getLineNumber()); - assertEquals(3, cr.getColumnNumber()); - } - - public void testTwoLinerR() throws IOException { - StringReader sr = new StringReader("a\rA"); - CountingReader cr = new CountingReader(sr); - int c; - c = cr.read(); - assertEquals('a', c); - assertEquals(0, cr.getLineNumber()); - assertEquals(1, cr.getColumnNumber()); - c = cr.read(); - assertEquals('\r', c); - assertEquals(1, cr.getLineNumber()); - assertEquals(0, cr.getColumnNumber()); - c = cr.read(); - assertEquals('A', c); - assertEquals(1, cr.getLineNumber()); - assertEquals(1, cr.getColumnNumber()); - c = cr.read(); - assertEquals(-1, c); - assertEquals(1, cr.getLineNumber()); - assertEquals(1, cr.getColumnNumber()); - } - public void testTwoLinerN() throws IOException { - StringReader sr = new StringReader("a\nA"); - CountingReader cr = new CountingReader(sr); - int c; - c = cr.read(); - assertEquals('a', c); - assertEquals(0, cr.getLineNumber()); - assertEquals(1, cr.getColumnNumber()); - c = cr.read(); - assertEquals('\n', c); - assertEquals(1, cr.getLineNumber()); - assertEquals(0, cr.getColumnNumber()); - c = cr.read(); - assertEquals('A', c); - assertEquals(1, cr.getLineNumber()); - assertEquals(1, cr.getColumnNumber()); - c = cr.read(); - assertEquals(-1, c); - assertEquals(1, cr.getLineNumber()); - assertEquals(1, cr.getColumnNumber()); - } - - public void testTwoLinerRN() throws IOException { - StringReader sr = new StringReader("a\r\nA"); - CountingReader cr = new CountingReader(sr); - int c; - c = cr.read(); - assertEquals('a', c); - assertEquals(0, cr.getLineNumber()); - assertEquals(1, cr.getColumnNumber()); - c = cr.read(); - assertEquals('\r', c); - assertEquals(1, cr.getLineNumber()); - assertEquals(0, cr.getColumnNumber()); - c = cr.read(); - assertEquals('\n', c); - assertEquals(1, cr.getLineNumber()); - assertEquals(0, cr.getColumnNumber()); - c = cr.read(); - assertEquals('A', c); - assertEquals(1, cr.getLineNumber()); - assertEquals(1, cr.getColumnNumber()); - c = cr.read(); - assertEquals(-1, c); - assertEquals(1, cr.getLineNumber()); - assertEquals(1, cr.getColumnNumber()); - } -} diff --git a/tests/src/java/org/apache/log4j/lbel/EventEvaluationTest.java b/tests/src/java/org/apache/log4j/lbel/EventEvaluationTest.java deleted file mode 100644 index cb905760f5..0000000000 --- a/tests/src/java/org/apache/log4j/lbel/EventEvaluationTest.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.lbel; - - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.apache.log4j.Level; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.LocationInfo; - - - -public class EventEvaluationTest extends TestCase { - LoggingEvent event; - LoggingEvent nullEvent; - - EventEvaluator evaluator; - - public EventEvaluationTest(String arg0) { - super(arg0); - } - - protected void setUp() throws Exception { - super.setUp(); - nullEvent = new LoggingEvent(); - event = new LoggingEvent(); - event.setLevel(Level.INFO); - event.setMessage("hello world"); - event.setLoggerName("org.wombat"); - event.setProperty("x", "y follows x"); - - LocationInfo li = new LocationInfo("file", "org.wombat", "getWombat", "10"); - event.setLocationInformation(li); - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - - public void testLevel() throws ScanError { - evaluator = new LBELEventEvaluator("level = DEBUG"); - assertTrue(!evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("level = INFO"); - assertTrue(evaluator.evaluate(event)); - } - - public void testMessage() throws ScanError { - evaluator = new LBELEventEvaluator("message = 'hello world'"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("message = hello"); - assertTrue(!evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("message != hello"); - assertTrue(evaluator.evaluate(event)); - - - evaluator = new LBELEventEvaluator("message > hello"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("message >= hello"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("message < hello"); - assertTrue(!evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("message <= hello"); - assertTrue(!evaluator.evaluate(event)); - } - - public void testRegexMessage() throws Exception, ScanError { - evaluator = new LBELEventEvaluator("message ~ 'hello'"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("message ~ 'h[a-z]* world'"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("message ~ 'h\\w* world'"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("message ~ 'hello\\sworld'"); - assertTrue(evaluator.evaluate(event)); - - LBELEventEvaluator evaluator = new LBELEventEvaluator("message !~ 'x'"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("message !~ 'x[a-z]* world'"); - assertTrue(evaluator.evaluate(event)); - } - - public void testLogger() throws Exception, ScanError { - evaluator = new LBELEventEvaluator("logger = 'org.wombat'"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("logger = 'org.wombat.x'"); - assertTrue(!evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("logger != 'org.wombat.x'"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("logger < 'org.wombat.x'"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("logger <= 'org.wombat.x'"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("logger > org"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("logger >= org"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("logger CHILDOF org"); - assertTrue(evaluator.evaluate(event)); - } - - public void testProperty() throws ScanError { - evaluator = new LBELEventEvaluator("property.x = 'y follows x'"); - assertTrue(evaluator.evaluate(event)); - evaluator = new LBELEventEvaluator("property.x >= 'y follows x'"); - assertTrue(evaluator.evaluate(event)); - evaluator = new LBELEventEvaluator("property.x <= 'y follows x'"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("property.x != 'y'"); - assertTrue(evaluator.evaluate(event)); - evaluator = new LBELEventEvaluator("property.x > 'y'"); - assertTrue(evaluator.evaluate(event)); - evaluator = new LBELEventEvaluator("property.x >= 'y'"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("property.y = 'toto'"); - assertTrue(!evaluator.evaluate(event)); - } - - public void testMethod() throws ScanError { - evaluator = new LBELEventEvaluator("method = getWombat"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("method >= get"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("method <= get"); - assertTrue(!evaluator.evaluate(event)); - - } - - public void testClass() throws ScanError { - evaluator = new LBELEventEvaluator("class = 'org.wombat'"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("class > org"); - assertTrue(evaluator.evaluate(event)); - - evaluator = new LBELEventEvaluator("class < org"); - assertTrue(!evaluator.evaluate(event)); - } - - public void testNull() throws ScanError { - evaluator = new LBELEventEvaluator("message = NULL"); - assertTrue(evaluator.evaluate(nullEvent)); - - evaluator = new LBELEventEvaluator("message != NULL"); - assertTrue(!evaluator.evaluate(nullEvent)); - - evaluator = new LBELEventEvaluator("message != NULL"); - assertTrue(evaluator.evaluate(event)); - - try { - evaluator = new LBELEventEvaluator("message > NULL"); - assertTrue(evaluator.evaluate(nullEvent)); - fail("NullPointerException should have been thrown"); - } catch(NullPointerException ne) { - } - - try { - evaluator = new LBELEventEvaluator("message > x"); - assertTrue(evaluator.evaluate(nullEvent)); - fail("NullPointerException should have been thrown"); - } catch(NullPointerException ne) { - } - - } - - - public static Test XXsuite() { - TestSuite suite = new TestSuite(); - //suite.addTest(new ParserTest("testAndOr")); - suite.addTest(new EventEvaluationTest("testLevel")); - return suite; - } - -} diff --git a/tests/src/java/org/apache/log4j/lbel/ParserTest.java b/tests/src/java/org/apache/log4j/lbel/ParserTest.java deleted file mode 100644 index 6d345baf4c..0000000000 --- a/tests/src/java/org/apache/log4j/lbel/ParserTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.lbel; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import java.io.IOException; -import java.io.StringReader; - -public class ParserTest extends TestCase { - Node top; - Node left; - Node right; - - public ParserTest(String arg0) { - super(arg0); - } - - protected void setUp() throws Exception { - super.setUp(); - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - - public void testTrue() throws IOException, ScanError { - StringReader sr = new StringReader("true"); - TokenStream ts = new TokenStream(sr); - Parser parser = new Parser(ts); - top = parser.parse(); - - assertEquals(Node.TRUE, top.getType()); - assertNull(top.getLeft()); - assertNull(top.getRight()); - //System.out.println("============"); - //top.leftFirstDump(""); - } - - public void testTrueOrFalse() throws IOException, ScanError { - StringReader sr = new StringReader("true OR false"); - TokenStream ts = new TokenStream(sr); - Parser parser = new Parser(ts); - top = parser.parse(); -// assertEquals(Node.E, top.getType()); -// -// top = top.getLeftSide(); -// assertEquals(Node.DIGIT, top.getType()); -// assertEquals(9, ((Integer) top.getValue()).intValue()); -// assertNull(top.getMiddle()); -// assertNull(top.getRightSide()); - System.out.println("============"); - top.leftFirstDump(""); - } - - public void testNotTrue() throws IOException, ScanError { - StringReader sr = new StringReader("not true"); - TokenStream ts = new TokenStream(sr); - Parser parser = new Parser(ts); - top = parser.parse(); - } - - public void testAndOr() throws IOException, ScanError { - StringReader sr = new StringReader("true or false and true"); - TokenStream ts = new TokenStream(sr); - Parser parser = new Parser(ts); - top = parser.parse(); - System.out.println("============"); - top.leftFirstDump(""); - } - - public void testParatheses() throws IOException, ScanError { - StringReader sr = new StringReader("(true or false)"); - TokenStream ts = new TokenStream(sr); - Parser parser = new Parser(ts); - top = parser.parse(); - System.out.println("============"); - top.leftFirstDump(""); - } - - public void testParatheses2() throws IOException, ScanError { - StringReader sr = new StringReader("(not (true or false)) and true"); - TokenStream ts = new TokenStream(sr); - Parser parser = new Parser(ts); - top = parser.parse(); - System.out.println("============"); - top.leftFirstDump(""); - } - - public static Test suite() { - TestSuite suite = new TestSuite(); - //suite.addTest(new ParserTest("testAndOr")); - suite.addTest(new ParserTest("testParatheses2")); - return suite; - } - -} diff --git a/tests/src/java/org/apache/log4j/lbel/ScanErrorTest.java b/tests/src/java/org/apache/log4j/lbel/ScanErrorTest.java deleted file mode 100644 index a1cdd6105a..0000000000 --- a/tests/src/java/org/apache/log4j/lbel/ScanErrorTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.lbel; - -import junit.framework.TestCase; - - -/** - * - * @author Ceki Gülcü - */ -public class ScanErrorTest extends TestCase { - - - public ScanErrorTest(String arg0) { - super(arg0); - } - - protected void setUp() throws Exception { - super.setUp(); - } - - protected void tearDown() throws Exception { - super.tearDown(); - } -} diff --git a/tests/src/java/org/apache/log4j/lbel/TokenStreamTest.java b/tests/src/java/org/apache/log4j/lbel/TokenStreamTest.java deleted file mode 100644 index 382cd20041..0000000000 --- a/tests/src/java/org/apache/log4j/lbel/TokenStreamTest.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.lbel; - -import junit.framework.TestCase; - -import java.io.IOException; -import java.io.StringReader; - - -public class TokenStreamTest extends TestCase { - Token t; - - public TokenStreamTest(String arg0) { - super(arg0); - } - - protected void setUp() throws Exception { - super.setUp(); - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - - public void testSingleDigit() throws IOException, ScanError { - StringReader sr = new StringReader("9"); - TokenStream ts = new TokenStream(sr); - - assertNull(ts.getCurrent()); - ts.next(); - - t = ts.getCurrent(); - assertEquals(Token.NUMBER, t.getType()); - assertEquals(9, ((Long) t.getValue()).longValue()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.EOF, t.getType()); - } - - public void testLongerDigit() throws IOException, ScanError { - StringReader sr = new StringReader(" 980 "); - TokenStream ts = new TokenStream(sr); - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.NUMBER, t.getType()); - assertEquals(980, ((Long) t.getValue()).longValue()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.EOF, t.getType()); - } - - public void testComparison() throws IOException, ScanError { - StringReader sr = new StringReader(" time >= 17"); - TokenStream ts = new TokenStream(sr); - ts.next(); - t = ts.getCurrent(); - - assertEquals(Token.LITERAL, t.getType()); - assertEquals("time", t.getValue()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.OPERATOR, t.getType()); - assertEquals(">=", t.getValue()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.NUMBER, t.getType()); - assertEquals(17, ((Long) t.getValue()).longValue()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.EOF, t.getType()); - } - - public void testRegex() throws IOException, ScanError { - StringReader sr = new StringReader(" time ~ x"); - TokenStream ts = new TokenStream(sr); - - ts.next(); t = ts.getCurrent(); - assertEquals(Token.LITERAL, t.getType()); - assertEquals("time", t.getValue()); - - ts.next(); t = ts.getCurrent(); - assertEquals(Token.OPERATOR, t.getType()); - assertEquals("~", t.getValue()); - - ts.next(); t = ts.getCurrent(); - assertEquals(Token.LITERAL, t.getType()); - assertEquals("x", t.getValue()); - } - - public void testNotRegex() throws IOException, ScanError { - StringReader sr = new StringReader(" t !~ x"); - TokenStream ts = new TokenStream(sr); - - ts.next(); t = ts.getCurrent(); - assertEquals(Token.LITERAL, t.getType()); - assertEquals("t", t.getValue()); - - ts.next(); t = ts.getCurrent(); - assertEquals(Token.OPERATOR, t.getType()); - assertEquals("!~", t.getValue()); - - ts.next(); t = ts.getCurrent(); - assertEquals(Token.LITERAL, t.getType()); - assertEquals("x", t.getValue()); - } - - - public void testFull() throws IOException, ScanError { - StringReader sr = new StringReader(" time >= 19 NOT \"hello world\" "); - TokenStream ts = new TokenStream(sr); - ts.next(); - t = ts.getCurrent(); - - assertEquals(Token.LITERAL, t.getType()); - assertEquals("time", t.getValue()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.OPERATOR, t.getType()); - assertEquals(">=", t.getValue()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.NUMBER, t.getType()); - assertEquals(19, ((Long) t.getValue()).longValue()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.NOT, t.getType()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.LITERAL, t.getType()); - assertEquals("hello world", t.getValue()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.EOF, t.getType()); - } - - public void testNoSpaceFull() throws IOException, ScanError { - StringReader sr = new StringReader(" time>=19 NOT \"hello world\" "); - TokenStream ts = new TokenStream(sr); - ts.next(); - t = ts.getCurrent(); - - assertEquals(Token.LITERAL, t.getType()); - assertEquals("time", t.getValue()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.OPERATOR, t.getType()); - assertEquals(">=", t.getValue()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.NUMBER, t.getType()); - assertEquals(19, ((Long) t.getValue()).longValue()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.NOT, t.getType()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.LITERAL, t.getType()); - assertEquals("hello world", t.getValue()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.EOF, t.getType()); - } - - public void testSingleQuote() throws IOException, ScanError { - StringReader sr = new StringReader(" logger ~ 'hello world' "); - TokenStream ts = new TokenStream(sr); - ts.next(); - t = ts.getCurrent(); - - assertEquals(Token.LOGGER, t.getType()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.OPERATOR, t.getType()); - assertEquals("~", t.getValue()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.LITERAL, t.getType()); - assertEquals("hello world", t.getValue()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.EOF, t.getType()); - } - - public void testTrueOrFalse() throws IOException, ScanError { - StringReader sr = new StringReader(" true OR false"); - TokenStream ts = new TokenStream(sr); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.TRUE, t.getType()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.OR, t.getType()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.FALSE, t.getType()); - - ts.next(); - t = ts.getCurrent(); - assertEquals(Token.EOF, t.getType()); - } - - public void testProperty() throws IOException, ScanError { - StringReader sr = new StringReader(" property.x property.xyz property."); - TokenStream ts = new TokenStream(sr); - - ts.next(); t = ts.getCurrent(); - assertEquals(Token.PROPERTY, t.getType()); - ts.next(); t = ts.getCurrent(); - assertEquals(Token.DOT, t.getType()); - ts.next(); t = ts.getCurrent(); - assertEquals(Token.LITERAL, t.getType()); - assertEquals("x", t.getValue()); - - ts.next(); t = ts.getCurrent(); - assertEquals(Token.PROPERTY, t.getType()); - ts.next(); t = ts.getCurrent(); - assertEquals(Token.DOT, t.getType()); - ts.next(); t = ts.getCurrent(); - assertEquals(Token.LITERAL, t.getType()); - assertEquals("xyz", t.getValue()); - - ts.next(); t = ts.getCurrent(); - assertEquals(Token.PROPERTY, t.getType()); - ts.next(); t = ts.getCurrent(); - assertEquals(Token.DOT, t.getType()); - - } - - - public void testQuotedProperty() throws IOException, ScanError { - - StringReader sr = new StringReader(" property.'toto a' etc"); - TokenStream ts = new TokenStream(sr); - - ts.next(); t = ts.getCurrent(); - assertEquals(Token.PROPERTY, t.getType()); - ts.next(); t = ts.getCurrent(); - assertEquals(Token.DOT, t.getType()); - ts.next(); t = ts.getCurrent(); - assertEquals(Token.LITERAL, t.getType()); - assertEquals("toto a", t.getValue()); - } -} diff --git a/tests/src/java/org/apache/log4j/multiplex/MultiplexAppenderTest.java b/tests/src/java/org/apache/log4j/multiplex/MultiplexAppenderTest.java deleted file mode 100644 index c7770e182b..0000000000 --- a/tests/src/java/org/apache/log4j/multiplex/MultiplexAppenderTest.java +++ /dev/null @@ -1,105 +0,0 @@ -package org.apache.log4j.multiplex; - -import junit.framework.TestCase; - -import org.apache.log4j.ConsoleAppender; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.MDC; -import org.apache.log4j.PatternLayout; -import org.apache.log4j.multiplex.AppenderFactory; -import org.apache.log4j.multiplex.AppenderFactoryUtils; -import org.apache.log4j.multiplex.MDCKeySelector; -import org.apache.log4j.multiplex.MultiplexAppender; -import org.apache.log4j.rolling.RollingFileAppender; -import org.apache.log4j.rolling.TimeBasedRollingPolicy; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.util.Compare; - -/** - * @author psmith - * - */ -public class MultiplexAppenderTest extends TestCase { - private Logger root; - - private Logger logger = Logger - .getLogger(MultiplexAppenderTest.class); - - public void setUp() { - root = Logger.getRootLogger(); - root.addAppender(new ConsoleAppender(new PatternLayout( - "%d{ABSOLUTE} %c{1} [%properties{User}] %m%n") )); - } - - public void testIllegalStates() { - MultiplexAppender appender = null; - - appender = new MultiplexAppender(); - try { - appender.activateOptions(); - fail("Should have thrown an IllegalStateException because it should not be configured correctly"); - } catch (Exception e) { - // expected - } - - appender = null; - } - - /* - * (non-Javadoc) - * - * @see junit.framework.TestCase#tearDown() - */ - protected void tearDown() throws Exception { - super.tearDown(); - LogManager.shutdown(); - } - - public void testMDCSelector() throws Exception { - - - MultiplexAppender appender = new MultiplexAppender(); - - final String mdcKey = "User"; - MDCKeySelector selector = new MDCKeySelector(mdcKey); - appender.setSelector(selector); - selector.setAppenderFactory(AppenderFactoryUtils.createSimpleMDCbasedFileAppender("output/MultiplexRollingFileAppenderTestMDC", mdcKey, new PatternLayout("%m%n"))); - selector.activateOptions(); - - - logger.addAppender(appender); - - MDC.put(mdcKey, "Bob"); - - logger.debug("Hello Bob"); - - MDC.put(mdcKey, "Jane"); - logger.debug("Hello Jane"); - - MDC.put(mdcKey, "Bob"); - logger.debug("I wonder what Jane's file looks like"); - - - MDC.put(mdcKey, "Jane"); - logger.debug("Bob. Be quiet."); - - - assertTrue("Bob's file does not match expected", Compare.compare("witness/multiplex/multiplex-test1_bob.txt", "output/MultiplexRollingFileAppenderTestMDC_Bob.log")); - assertTrue("Jane's file does not match expected", Compare.compare("witness/multiplex/multiplex-test1_jane.txt", "output/MultiplexRollingFileAppenderTestMDC_Jane.log")); - - } - - // TODO we need a test that tests when the MDC value is null/not found - - public void testcreateMDCAndDailyRollingAppenderFactory() { - AppenderFactory factory = AppenderFactoryUtils.createMDCAndDailyRollingAppenderFactory("output/standardMDC", "User", new PatternLayout("%m%n")); - MDC.put("User", "Bob"); - LoggingEvent e = new LoggingEvent(); - - RollingFileAppender appender = (RollingFileAppender) factory.create(e); - - assertEquals(appender.getTriggeringPolicy().getClass(), TimeBasedRollingPolicy.class); - //TimeBasedRollingPolicy policy =(TimeBasedRollingPolicy) appender.getTriggeringPolicy(); - } -} \ No newline at end of file diff --git a/tests/src/java/org/apache/log4j/net/SMTPAppenderTest.java b/tests/src/java/org/apache/log4j/net/SMTPAppenderTest.java index d55168876e..583a5bd85d 100644 --- a/tests/src/java/org/apache/log4j/net/SMTPAppenderTest.java +++ b/tests/src/java/org/apache/log4j/net/SMTPAppenderTest.java @@ -14,137 +14,49 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.log4j.net; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.net.ServerSocket; -import java.net.Socket; - -import org.apache.log4j.AbstractAppenderTest; -import org.apache.log4j.AppenderSkeleton; +import junit.framework.TestCase; +import org.apache.log4j.LogManager; import org.apache.log4j.Logger; -import org.apache.log4j.PatternLayout; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.spi.TriggeringEventEvaluator; +import org.apache.log4j.xml.DOMConfigurator; /** - * Test if SMTPAppender honors the Appender contract. - * - * @author Ceki Gülcü - * + * Tests for SMTPAppender. */ -public class SMTPAppenderTest extends AbstractAppenderTest { - - SMTPAppender ca = new SMTPAppender(); - - protected void setUp() { - ca.setLayout(new PatternLayout("%m%n")); - ca.setFrom("from@example.net"); - ca.setTo("to@example.net"); - ca.setSMTPHost("localhost"); - ca.setSubject("subject"); - } - - protected void tearDown() { - ca.close(); - } - - protected AppenderSkeleton getAppender() { - return ca; - } - - public AppenderSkeleton getConfiguredAppender() { - return ca; - } - - public class MailServer extends Thread { - ServerSocket ss; - String enc = "ASCII"; - StringBuffer sb = new StringBuffer(); - - MailServer() throws Exception { - ss = new ServerSocket(0); - } - - public void run() { - while (!Thread.interrupted()) { - try { - run0(); - } catch (IOException e) { - System.out.println(e); - } - } - } - - private void println(Writer w, String s) throws IOException { - w.write(s); - w.write("\r\n"); - w.flush(); - } - - private void run0() throws IOException { - Socket s; - s = ss.accept(); - BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream(), enc)); - BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream(), enc)); - println(bw, "220 SMTP"); - String helo = br.readLine(); - println(bw, "250 OK"); - String from = br.readLine(); - println(bw, "250 OK"); - String to = br.readLine(); - println(bw, "250 OK"); - String data = br.readLine(); - println(bw, "354 send, end with ."); - String line; - while (true) { - line = br.readLine(); - sb.append(line).append("\r\n"); - if (line.equals(".")) break; - } - System.out.println(sb); - println(bw, "250 OK"); - String quit = br.readLine(); - s.close(); +public class SMTPAppenderTest extends TestCase { + public SMTPAppenderTest(final String testName) { + super(testName); } + /** + * Reset configuration after every test. + */ + public void tearDown() { + LogManager.resetConfiguration(); } - public void testSend() throws Exception { - MailServer server = new MailServer(); - server.start(); - ca.setSMTPPort(server.ss.getLocalPort()); - ca.activateOptions(); - - String msg = "XYZZY"; - Logger l = Logger.getLogger(getClass()); - l.addAppender(ca); - l.error(msg); - Thread.sleep(500); - server.interrupt(); - server.ss.close(); - - String s = server.sb.toString(); - assertTrue("got the message", s.indexOf(msg) != -1); - assertTrue(s.indexOf(ca.getFrom()) != -1); - assertTrue(s.indexOf(ca.getTo()) != -1); - assertTrue(s.indexOf(ca.getSubject()) != -1); + /** + * Trivial implementation of TriggeringEventEvaluator. + */ + public static final class MockTriggeringEventEvaluator implements TriggeringEventEvaluator { + /** + * {@inheritDoc} + */ + public boolean isTriggeringEvent(final LoggingEvent event) { + return true; + } } - public void testBadSessionJNDI() { - ca.setSessionJNDI("/not/here"); - try { - ca.activateOptions(); - fail("cannot start"); - } catch (IllegalStateException e) { - } - ca.setSessionJNDI(null); - ca.setLayout(new DummyLayout()); - ca.activateOptions(); + /** + * Tests that triggeringPolicy element will set evaluator. + */ + public void testTrigger() { + DOMConfigurator.configure("input/xml/smtpAppender1.xml"); + SMTPAppender appender = (SMTPAppender) Logger.getRootLogger().getAppender("A1"); + TriggeringEventEvaluator evaluator = appender.getEvaluator(); + assertTrue(evaluator instanceof MockTriggeringEventEvaluator); } - } diff --git a/tests/src/java/org/apache/log4j/net/ShortSocketServer.java b/tests/src/java/org/apache/log4j/net/ShortSocketServer.java index ddda2295bf..78eee86905 100644 --- a/tests/src/java/org/apache/log4j/net/ShortSocketServer.java +++ b/tests/src/java/org/apache/log4j/net/ShortSocketServer.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,76 +15,71 @@ * limitations under the License. */ -package org.apache.log4j.net; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.MDC; -import org.apache.log4j.PropertyConfigurator; -import org.apache.log4j.net.SocketNode; +package org.apache.log4j.net; -import java.net.ServerSocket; import java.net.Socket; +import java.net.ServerSocket; +import org.apache.log4j.Logger; +import org.apache.log4j.LogManager; +import org.apache.log4j.PropertyConfigurator; +import org.apache.log4j.MDC; +import org.apache.log4j.helpers.LogLog; /** * This SocketServer exits after certain number of connections from a * client. This number is determined the totalsTest parameter, that is * the first argument on the commmand line. The second argument, * prefix, determines the prefix of the configuration file to - * use. - * - * Each run of the server will use a different properties file. For the i-th - * run, the path to the file is (prefix+i+".properties"). - * - * There is strong coupling between this class and SocketServerTestCase. When - * a test case in SocketServerTestCase tears down its envrionment, it will - * close its SocketAppender which will cause the SocketNode thread to die, - * allowing the next test case to start. See the for loop within the main method - * of this class. + * use. Each run of the server will use a different properties + * file. For the i-th run, the path to the file is + * (prefix+i+".properties"). * * @author Ceki Gulcu */ -public class ShortSocketServer { - static Logger logger = Logger.getLogger(ShortSocketServer.class); - public static void main(String[] args) throws Exception { +public class ShortSocketServer { + + static Logger cat = Logger.getLogger(ShortSocketServer.class); + + public + static + void main(String args[]) throws Exception { int totalTests = 0; String prefix = null; - if (args.length == 2) { + if(args.length == 2) { totalTests = Integer.parseInt(args[0]); prefix = args[1]; } else { - usage("Wrong number of arguments."); + usage("Wrong number of arguments."); } + - logger.debug("Listening on port " + SocketServerTestCase.PORT); + LogLog.debug("Listening on port " + SocketServerTestCase.PORT); + ServerSocket serverSocket = new ServerSocket(SocketServerTestCase.PORT); - ServerSocket serverSocket = new ServerSocket(SocketServerTestCase.PORT); + MDC.put("hostID", "shortSocketServer"); - MDC.put("hostID", "shortSocketServer"); - - for (int i = 1; i <= totalTests; i++) { - PropertyConfigurator.configure(prefix + i + ".properties"); - logger.debug("Waiting to accept a new client."); - - Socket socket = serverSocket.accept(); - logger.debug("Connected to client at " + socket.getInetAddress()); - logger.debug("Starting new socket node."); - - SocketNode sn = new SocketNode(socket, LogManager.getLoggerRepository()); - Thread t = new Thread(sn); - t.start(); - // sn will die when an incoming connection is closed. - t.join(); - } + for(int i = 1; i <= totalTests; i++) { + PropertyConfigurator.configure(prefix+i+".properties"); + LogLog.debug("Waiting to accept a new client."); + Socket socket = serverSocket.accept(); + LogLog.debug("Connected to client at " + socket.getInetAddress()); + LogLog.debug("Starting new socket node."); + SocketNode sn = new SocketNode(socket, LogManager.getLoggerRepository()); + Thread t = new Thread(sn); + t.start(); + t.join(); + } } - static void usage(String msg) { + + static + void usage(String msg) { System.err.println(msg); System.err.println( - "Usage: java " + ShortSocketServer.class.getName() - + " totalTests configFilePrefix"); + "Usage: java " +ShortSocketServer.class.getName() + " totalTests configFilePrefix"); System.exit(1); - } + } } diff --git a/tests/src/java/org/apache/log4j/net/SocketAppenderTest.java b/tests/src/java/org/apache/log4j/net/SocketAppenderTest.java new file mode 100644 index 0000000000..3cb6bc52d1 --- /dev/null +++ b/tests/src/java/org/apache/log4j/net/SocketAppenderTest.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.net; + +import junit.framework.TestCase; +import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.Logger; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.xml.DOMConfigurator; + +public class SocketAppenderTest extends TestCase { + + /** + * Create new instance. + */ + public SocketAppenderTest(final String testName) { + super(testName); + } + + /* JUnit's setUp and tearDown */ + + protected void setUp() { + DOMConfigurator.configure("input/xml/SocketAppenderTestConfig.xml"); + + logger = Logger.getLogger(SocketAppenderTest.class); + secondary = (LastOnlyAppender) Logger.getLogger( + "org.apache.log4j.net.SocketAppenderTestDummy").getAppender("lastOnly"); + } + + protected void tearDown() { + } + + /* Tests */ + + public void testFallbackErrorHandlerWhenStarting() { + String msg = "testFallbackErrorHandlerWhenStarting"; + logger.debug(msg); + + // above debug log will fail and shoul be redirected to secondary appender + assertEquals("SocketAppender with FallbackErrorHandler", msg, secondary.getLastMessage()); + } + + /* Fields */ + + private static Logger logger; + private static LastOnlyAppender secondary; + + /* Inner classes */ + + /** + * Inner-class For debugging purposes only Saves last LoggerEvent + */ + static public class LastOnlyAppender extends AppenderSkeleton { + protected void append(LoggingEvent event) { + this.lastEvent = event; + } + + public boolean requiresLayout() { + return false; + } + + public void close() { + this.closed = true; + } + + /** + * @return last appended LoggingEvent's message + */ + public String getLastMessage() { + if (this.lastEvent != null) { + return this.lastEvent.getMessage().toString(); + } else { + return ""; + } + } + + private LoggingEvent lastEvent; + }; + +} \ No newline at end of file diff --git a/tests/src/java/org/apache/log4j/net/SocketServerTestCase.java b/tests/src/java/org/apache/log4j/net/SocketServerTestCase.java index 15a2e7293b..59194076a3 100644 --- a/tests/src/java/org/apache/log4j/net/SocketServerTestCase.java +++ b/tests/src/java/org/apache/log4j/net/SocketServerTestCase.java @@ -17,66 +17,71 @@ package org.apache.log4j.net; -import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import junit.framework.Test; import org.apache.log4j.*; +import org.apache.log4j.util.*; + + import org.apache.log4j.Logger; import org.apache.log4j.NDC; -import org.apache.log4j.util.*; import org.apache.log4j.xml.XLevel; - /** - * - * @author Ceki Gülcü + @author Ceki Gülcü */ public class SocketServerTestCase extends TestCase { + static String TEMP = "output/temp"; static String FILTERED = "output/filtered"; // %5p %x [%t] %c %m%n // DEBUG T1 [main] org.apache.log4j.net.SocketAppenderTestCase Message 1 - static String PAT1 = - "^(DEBUG| INFO| WARN|ERROR|FATAL|LETHAL) T1 \\[main]\\ " - + ".* Message \\d{1,2}"; + static String PAT1 = "^(TRACE|DEBUG| INFO| WARN|ERROR|FATAL|LETHAL) T1 \\[main]\\ " + + ".* Message \\d{1,2}"; // DEBUG T2 [main] ? (?:?) Message 1 - static String PAT2 = - "^(DEBUG| INFO| WARN|ERROR|FATAL|LETHAL) T2 \\[main]\\ " - + "\\? \\(\\?:\\?\\) Message \\d{1,2}"; + static String PAT2 = "^(TRACE|DEBUG| INFO| WARN|ERROR|FATAL|LETHAL) T2 \\[main]\\ " + + "\\? \\(\\?:\\?\\) Message \\d{1,2}"; + // DEBUG T3 [main] org.apache.log4j.net.SocketServerTestCase (SocketServerTestCase.java:121) Message 1 - static String PAT3 = - "^(DEBUG| INFO| WARN|ERROR|FATAL|LETHAL) T3 \\[main]\\ " - + "org.apache.log4j.net.SocketServerTestCase " - + "\\(SocketServerTestCase.java:\\d{3}\\) Message \\d{1,2}"; + static String PAT3 = "^(TRACE|DEBUG| INFO| WARN|ERROR|FATAL|LETHAL) T3 \\[main]\\ " + + "org.apache.log4j.net.SocketServerTestCase " + + "\\(SocketServerTestCase.java:\\d{3}\\) Message \\d{1,2}"; + // DEBUG some T4 MDC-TEST4 [main] SocketAppenderTestCase - Message 1 // DEBUG some T4 MDC-TEST4 [main] SocketAppenderTestCase - Message 1 - static String PAT4 = - "^(DEBUG| INFO| WARN|ERROR|FATAL|LETHAL) some T4 MDC-TEST4 \\[main]\\" - + " (root|SocketServerTestCase) - Message \\d{1,2}"; - static String PAT5 = - "^(DEBUG| INFO| WARN|ERROR|FATAL|LETHAL) some5 T5 MDC-TEST5 \\[main]\\" - + " (root|SocketServerTestCase) - Message \\d{1,2}"; - static String PAT6 = - "^(DEBUG| INFO| WARN|ERROR|FATAL|LETHAL) some6 T6 client-test6 MDC-TEST6" - + " \\[main]\\ (root|SocketServerTestCase) - Message \\d{1,2}"; - static String PAT7 = - "^(DEBUG| INFO| WARN|ERROR|FATAL|LETHAL) some7 T7 client-test7 MDC-TEST7" - + " \\[main]\\ (root|SocketServerTestCase) - Message \\d{1,2}"; + static String PAT4 = "^(TRACE|DEBUG| INFO| WARN|ERROR|FATAL|LETHAL) some T4 MDC-TEST4 \\[main]\\" + + " (root|SocketServerTestCase) - Message \\d{1,2}"; + + static String PAT5 = "^(TRACE|DEBUG| INFO| WARN|ERROR|FATAL|LETHAL) some5 T5 MDC-TEST5 \\[main]\\" + + " (root|SocketServerTestCase) - Message \\d{1,2}"; + + static String PAT6 = "^(TRACE|DEBUG| INFO| WARN|ERROR|FATAL|LETHAL) some6 T6 client-test6 MDC-TEST6" + + " \\[main]\\ (root|SocketServerTestCase) - Message \\d{1,2}"; + + static String PAT7 = "^(TRACE|DEBUG| INFO| WARN|ERROR|FATAL|LETHAL) some7 T7 client-test7 MDC-TEST7" + + " \\[main]\\ (root|SocketServerTestCase) - Message \\d{1,2}"; // DEBUG some8 T8 shortSocketServer MDC-TEST7 [main] SocketServerTestCase - Message 1 - static String PAT8 = - "^(DEBUG| INFO| WARN|ERROR|FATAL|LETHAL) some8 T8 shortSocketServer" - + " MDC-TEST8 \\[main]\\ (root|SocketServerTestCase) - Message \\d{1,2}"; + static String PAT8 = "^(TRACE|DEBUG| INFO| WARN|ERROR|FATAL|LETHAL) some8 T8 shortSocketServer" + + " MDC-TEST8 \\[main]\\ (root|SocketServerTestCase) - Message \\d{1,2}"; + + + static String EXCEPTION1 = "java.lang.Exception: Just testing"; - static String EXCEPTION2 = "\\s*at .*\\(.*:\\d{1,4}\\)"; + static String EXCEPTION2 = "\\s*at .*\\(.*\\)"; static String EXCEPTION3 = "\\s*at .*\\(Native Method\\)"; + static String EXCEPTION4 = "\\s*at .*\\(.*Compiled Code\\)"; + static String EXCEPTION5 = "\\s*at .*\\(.*libgcj.*\\)"; + + static Logger logger = Logger.getLogger(SocketServerTestCase.class); - public static final int PORT = 12073; + static public final int PORT = 12345; static Logger rootLogger = Logger.getRootLogger(); SocketAppender socketAppender; @@ -87,7 +92,7 @@ public SocketServerTestCase(String name) { public void setUp() { System.out.println("Setting up test case."); } - + public void tearDown() { System.out.println("Tearing down test case."); socketAppender = null; @@ -95,27 +100,25 @@ public void tearDown() { } /** - * The pattern on the server side: %5p %x [%t] %c %m%n + * The pattern on the server side: %5p %x [%t] %c %m%n * - * We are testing NDC functionality across the wire. + * We are testing NDC functionality across the wire. */ public void test1() throws Exception { socketAppender = new SocketAppender("localhost", PORT); rootLogger.addAppender(socketAppender); common("T1", "key1", "MDC-TEST1"); delay(1); - - ControlFilter cf = - new ControlFilter( - new String[] { PAT1, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); - + ControlFilter cf = new ControlFilter(new String[]{PAT1, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); + Transformer.transform( TEMP, FILTERED, new Filter[] { cf, new LineNumberFilter(), new JunitTestRunnerFilter(), new SunReflectFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/net/socketServer.1")); + assertTrue(Compare.compare(FILTERED, "witness/socketServer.1")); } /** @@ -130,18 +133,16 @@ public void test2() throws Exception { common("T2", "key2", "MDC-TEST2"); delay(1); - - ControlFilter cf = - new ControlFilter( - new String[] { PAT2, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); - + ControlFilter cf = new ControlFilter(new String[]{PAT2, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); + Transformer.transform( TEMP, FILTERED, new Filter[] { cf, new LineNumberFilter(), new JunitTestRunnerFilter(), new SunReflectFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/net/socketServer.2")); + assertTrue(Compare.compare(FILTERED, "witness/socketServer.2")); } /** @@ -155,24 +156,22 @@ public void test3() throws Exception { common("T3", "key3", "MDC-TEST3"); delay(1); - - ControlFilter cf = - new ControlFilter( - new String[] { PAT3, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); - + ControlFilter cf = new ControlFilter(new String[]{PAT3, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); + Transformer.transform( TEMP, FILTERED, new Filter[] { cf, new LineNumberFilter(), new JunitTestRunnerFilter(), new SunReflectFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/net/socketServer.3")); + assertTrue(Compare.compare(FILTERED, "witness/socketServer.3")); } /** - * The pattern on the server side: %5p %x %X{key1}%X{key4} [%t] %c{1} - %m%n - * meaning that we are testing NDC, MDC and localization functionality across - * the wire. + * The pattern on the server side: %5p %x %X{key1}%X{key4} [%t] %c{1} - %m%n + * meaning that we are testing NDC, MDC and localization functionality across + * the wire. */ public void test4() throws Exception { socketAppender = new SocketAppender("localhost", PORT); @@ -183,22 +182,25 @@ public void test4() throws Exception { common("T4", "key4", "MDC-TEST4"); NDC.pop(); delay(1); - - ControlFilter cf = - new ControlFilter( - new String[] { PAT4, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); - - Transformer.transform( - TEMP, FILTERED, - new Filter[] { cf, new LineNumberFilter(), - new JunitTestRunnerFilter(), - new SunReflectFilter() }); - - assertTrue(Compare.compare(FILTERED, "witness/net/socketServer.4")); + // + // These tests check MDC operation which + // requires JDK 1.2 or later + if(!System.getProperty("java.version").startsWith("1.1.")) { + + ControlFilter cf = new ControlFilter(new String[]{PAT4, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); + Transformer.transform( + TEMP, FILTERED, + new Filter[] { cf, new LineNumberFilter(), + new JunitTestRunnerFilter(), + new SunReflectFilter() }); + + assertTrue(Compare.compare(FILTERED, "witness/socketServer.4")); + } } /** - * The pattern on the server side: %5p %x %X{key1}%X{key5} [%t] %c{1} - %m%n + * The pattern on the server side: %5p %x %X{key1}%X{key5} [%t] %c{1} - %m%n * * The test case uses wraps an AsyncAppender around the * SocketAppender. This tests was written specifically for bug @@ -214,7 +216,6 @@ public void test4() throws Exception { public void test5() throws Exception { socketAppender = new SocketAppender("localhost", PORT); socketAppender.setLocationInfo(true); - AsyncAppender asyncAppender = new AsyncAppender(); asyncAppender.setLocationInfo(true); asyncAppender.addAppender(socketAppender); @@ -224,21 +225,25 @@ public void test5() throws Exception { common("T5", "key5", "MDC-TEST5"); NDC.pop(); delay(2); - - ControlFilter cf = - new ControlFilter( - new String[] { PAT5, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); - - Transformer.transform( - TEMP, FILTERED, - new Filter[] { cf, new LineNumberFilter(), - new JunitTestRunnerFilter(), - new SunReflectFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/net/socketServer.5")); + // + // These tests check MDC operation which + // requires JDK 1.2 or later + if(!System.getProperty("java.version").startsWith("1.1.")) { + ControlFilter cf = new ControlFilter(new String[]{PAT5, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); + + Transformer.transform( + TEMP, FILTERED, + new Filter[] { cf, new LineNumberFilter(), + new JunitTestRunnerFilter(), + new SunReflectFilter() }); + + assertTrue(Compare.compare(FILTERED, "witness/socketServer.5")); + } } /** - * The pattern on the server side: %5p %x %X{hostID}${key6} [%t] %c{1} - %m%n + * The pattern on the server side: %5p %x %X{hostID}${key6} [%t] %c{1} - %m%n * * This test checks whether client-side MDC overrides the server side. * It uses an AsyncAppender encapsulating a SocketAppender @@ -246,7 +251,6 @@ public void test5() throws Exception { public void test6() throws Exception { socketAppender = new SocketAppender("localhost", PORT); socketAppender.setLocationInfo(true); - AsyncAppender asyncAppender = new AsyncAppender(); asyncAppender.setLocationInfo(true); asyncAppender.addAppender(socketAppender); @@ -258,21 +262,25 @@ public void test6() throws Exception { NDC.pop(); MDC.remove("hostID"); delay(2); - - ControlFilter cf = - new ControlFilter( - new String[] { PAT6, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); - - Transformer.transform( - TEMP, FILTERED, - new Filter[] { cf, new LineNumberFilter(), - new JunitTestRunnerFilter(), - new SunReflectFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/net/socketServer.6")); + // + // These tests check MDC operation which + // requires JDK 1.2 or later + if(!System.getProperty("java.version").startsWith("1.1.")) { + ControlFilter cf = new ControlFilter(new String[]{PAT6, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); + + Transformer.transform( + TEMP, FILTERED, + new Filter[] { cf, new LineNumberFilter(), + new JunitTestRunnerFilter(), + new SunReflectFilter() }); + + assertTrue(Compare.compare(FILTERED, "witness/socketServer.6")); + } } /** - * The pattern on the server side: %5p %x %X{hostID}${key7} [%t] %c{1} - %m%n + * The pattern on the server side: %5p %x %X{hostID}${key7} [%t] %c{1} - %m%n * * This test checks whether client-side MDC overrides the server side. */ @@ -285,23 +293,26 @@ public void test7() throws Exception { MDC.put("hostID", "client-test7"); common("T7", "key7", "MDC-TEST7"); NDC.pop(); - MDC.remove("hostID"); + MDC.remove("hostID"); delay(2); - - ControlFilter cf = - new ControlFilter( - new String[] { PAT7, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); - - Transformer.transform( - TEMP, FILTERED, - new Filter[] { cf, new LineNumberFilter(), - new JunitTestRunnerFilter(), - new SunReflectFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/net/socketServer.7")); + // + // These tests check MDC operation which + // requires JDK 1.2 or later + if(!System.getProperty("java.version").startsWith("1.1.")) { + ControlFilter cf = new ControlFilter(new String[]{PAT7, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); + + Transformer.transform( + TEMP, FILTERED, + new Filter[] { cf, new LineNumberFilter(), + new JunitTestRunnerFilter(), + new SunReflectFilter() }); + assertTrue(Compare.compare(FILTERED, "witness/socketServer.7")); + } } /** - * The pattern on the server side: %5p %x %X{hostID}${key7} [%t] %c{1} - %m%n + * The pattern on the server side: %5p %x %X{hostID} ${key8} [%t] %c{1} - %m%n * * This test checks whether server side MDC works. */ @@ -311,51 +322,78 @@ public void test8() throws Exception { rootLogger.addAppender(socketAppender); NDC.push("some8"); + + // + // The test has relied on the receiving code to + // combine the sent MDC with the receivers MDC + // (which contains a value for hostID). + // The mechanism of how that happens is not clear + // and it does not work with Apache Harmony. + // Unclear if it is a Harmony issue. + if (System.getProperty("java.vendor").indexOf("Apache") != -1) { + MDC.put("hostID", "shortSocketServer"); + } + common("T8", "key8", "MDC-TEST8"); NDC.pop(); delay(2); - - ControlFilter cf = - new ControlFilter( - new String[] { PAT8, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); - - Transformer.transform( - TEMP, FILTERED, - new Filter[] { cf, new LineNumberFilter(), - new JunitTestRunnerFilter(), - new SunReflectFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/net/socketServer.8")); + // + // These tests check MDC operation which + // requires JDK 1.2 or later + if(!System.getProperty("java.version").startsWith("1.1.")) { + ControlFilter cf = new ControlFilter(new String[]{PAT8, EXCEPTION1, + EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); + + Transformer.transform( + TEMP, FILTERED, + new Filter[] { cf, new LineNumberFilter(), + new JunitTestRunnerFilter(), + new SunReflectFilter() }); + assertTrue(Compare.compare(FILTERED, "witness/socketServer.8")); + } } - static void common(String dc, String key, String o) { - int i = -1; - NDC.push(dc); - MDC.put(key, o); + static + void common(String dc, String key, Object o) { + String oldThreadName = Thread.currentThread().getName(); + Thread.currentThread().setName("main"); + int i = -1; + NDC.push(dc); + MDC.put(key, o); Logger root = Logger.getRootLogger(); + logger.setLevel(Level.DEBUG); + rootLogger.setLevel(Level.DEBUG); + logger.log(XLevel.TRACE, "Message " + ++i); + + logger.setLevel(Level.TRACE); + rootLogger.setLevel(Level.TRACE); + + logger.trace("Message " + ++i); + root.trace("Message " + ++i); logger.debug("Message " + ++i); root.debug("Message " + ++i); logger.info("Message " + ++i); logger.warn("Message " + ++i); logger.log(XLevel.LETHAL, "Message " + ++i); //5 - + Exception e = new Exception("Just testing"); logger.debug("Message " + ++i, e); root.error("Message " + ++i, e); NDC.pop(); MDC.remove(key); + + Thread.currentThread().setName(oldThreadName); } public void delay(int secs) { - try { - Thread.sleep(secs * 1000); - } catch (Exception e) { - } + try {Thread.sleep(secs*1000);} catch(Exception e) {} } - public static Test XXsuite() { + + public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(new SocketServerTestCase("test1")); suite.addTest(new SocketServerTestCase("test2")); @@ -365,7 +403,6 @@ public static Test XXsuite() { suite.addTest(new SocketServerTestCase("test6")); suite.addTest(new SocketServerTestCase("test7")); suite.addTest(new SocketServerTestCase("test8")); - return suite; } } diff --git a/tests/src/java/org/apache/log4j/net/SyslogAppenderTest.java b/tests/src/java/org/apache/log4j/net/SyslogAppenderTest.java index 2f417a383d..cec8ed829e 100644 --- a/tests/src/java/org/apache/log4j/net/SyslogAppenderTest.java +++ b/tests/src/java/org/apache/log4j/net/SyslogAppenderTest.java @@ -17,13 +17,6 @@ package org.apache.log4j.net; -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.ServerSocket; -import java.net.SocketException; -import java.util.StringTokenizer; - import junit.framework.TestCase; import org.apache.log4j.AsyncAppender; @@ -32,20 +25,24 @@ import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.apache.log4j.PatternLayout; -import org.apache.log4j.helpers.SyslogWriter; -import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.VectorErrorHandler; +import org.apache.log4j.HTMLLayout; + +import java.util.StringTokenizer; +import java.net.DatagramSocket; +import java.net.DatagramPacket; +import java.text.SimpleDateFormat; +import java.util.Locale; +import java.util.Date; +import java.util.Calendar; /** * Tests for SyslogAppender * - * @author Curt Arnold - **/ + * + * */ public class SyslogAppenderTest extends TestCase { - - DatagramSocket ds; - DatagramPacket p = new DatagramPacket(new byte[1000], 0, 1000); - /** * Create new instance of SyslogAppenderTest. * @param testName test name @@ -53,23 +50,16 @@ public class SyslogAppenderTest extends TestCase { public SyslogAppenderTest(final String testName) { super(testName); } - - protected void setUp() throws Exception { - ds = new DatagramSocket(); - ds.setSoTimeout(2000); - } /** * Resets configuration after every test. */ - protected void tearDown() { - ds.close(); + public void tearDown() { LogManager.resetConfiguration(); } /** * Test default constructor. - * @deprecated Since getFacilityPrinting is deprecated */ public void testDefaultConstructor() { SyslogAppender appender = new SyslogAppender(); @@ -77,12 +67,12 @@ public void testDefaultConstructor() { assertEquals(false, appender.getFacilityPrinting()); assertNull(appender.getLayout()); assertNull(appender.getSyslogHost()); + assertNull(appender.getTag()); assertTrue(appender.requiresLayout()); } /** * Test two parameter constructor. - * @deprecated Since getFacilityPrinting is deprecated */ public void testTwoParamConstructor() { Layout layout = new PatternLayout(); @@ -91,12 +81,12 @@ public void testTwoParamConstructor() { assertEquals(false, appender.getFacilityPrinting()); assertEquals(layout, appender.getLayout()); assertNull(appender.getSyslogHost()); + assertNull(appender.getTag()); assertTrue(appender.requiresLayout()); } /** * Test two parameter constructor with unexpected facility. - * @deprecated Since getFacilityPrinting is deprecated */ public void testTwoParamConstructorBadFacility() { Layout layout = new PatternLayout(); @@ -105,12 +95,12 @@ public void testTwoParamConstructorBadFacility() { assertEquals(false, appender.getFacilityPrinting()); assertEquals(layout, appender.getLayout()); assertNull(appender.getSyslogHost()); + assertNull(appender.getTag()); assertTrue(appender.requiresLayout()); } /** * Test three parameter constructor. - * @deprecated Since getFacilityPrinting is deprecated */ public void testThreeParamConstructor() { Layout layout = new PatternLayout(); @@ -120,12 +110,12 @@ public void testThreeParamConstructor() { assertEquals(false, appender.getFacilityPrinting()); assertEquals(layout, appender.getLayout()); assertEquals("syslog.example.org", appender.getSyslogHost()); + assertNull(appender.getTag()); assertTrue(appender.requiresLayout()); } /** * Test getFacilityString for expected facility codes. - * @deprecated Since getFacilityString is deprecated */ public void testGetFacilityString() { String expected = @@ -149,7 +139,6 @@ public void testGetFacilityString() { /** * Test getFacilityString for some unexpected facility codes. - * @deprecated Since getFacilityString is deprecated */ public void testGetFacilityStringUnexpected() { assertNull(SyslogAppender.getFacilityString(1)); @@ -202,7 +191,6 @@ public void testGetFacilityLocalNames() { /** * Test setFacilityPrinting. - * @deprecated Since get/setFacilityPrinting are deprecated */ public void testSetFacilityPrinting() { SyslogAppender appender = new SyslogAppender(); @@ -274,7 +262,6 @@ public void testSetFacilityBogus() { /** * Tests calling setFacility after appender has been activated. - * @deprecated Since setErrorHandler is deprecated */ public void testSetFacilityAfterActivation() { SyslogAppender appender = new SyslogAppender(); @@ -284,8 +271,7 @@ public void testSetFacilityAfterActivation() { appender.setFacility("user"); appender.setLayout(new PatternLayout("%m%n")); - org.apache.log4j.VectorErrorHandler errorHandler = - new org.apache.log4j.VectorErrorHandler(); + VectorErrorHandler errorHandler = new VectorErrorHandler(); appender.setErrorHandler(errorHandler); appender.activateOptions(); appender.setFacility("kern"); @@ -300,8 +286,6 @@ public void testSetFacilityAfterActivation() { public void testAppendBelowThreshold() { SyslogAppender appender = new SyslogAppender(); appender.setThreshold(Level.ERROR); - appender.setSyslogHost("localhost"); - appender.setLayout(new PatternLayout("%m%n")); appender.activateOptions(); Logger logger = Logger.getRootLogger(); @@ -312,34 +296,33 @@ public void testAppendBelowThreshold() { /** * Tests that append method drops messages below threshold. - * @deprecated Since setErrorHandler is deprecated */ public void testAppendNoHost() { SyslogAppender appender = new SyslogAppender(); appender.setName("foo"); appender.setThreshold(Level.INFO); - org.apache.log4j.VectorErrorHandler errorHandler = - new org.apache.log4j.VectorErrorHandler(); + VectorErrorHandler errorHandler = new VectorErrorHandler(); appender.setErrorHandler(errorHandler); appender.setLayout(new PatternLayout("%m%n")); + appender.activateOptions(); + + Logger logger = Logger.getRootLogger(); + logger.addAppender(appender); + logger.info( + "Should not be logged by SyslogAppenderTest.testAppendNoHost."); + assertEquals(1, errorHandler.size()); // - // log4j 1.2 would not throw exception on activateOptions - // but would call ErrorHandler on first log attempt + // Appender is misspelled in implementation // - try { - appender.activateOptions(); - } catch (IllegalStateException ex) { - return; - } - - fail("Expected IllegalStateException"); + assertEquals( + "No syslog host is set for SyslogAppedender named \"foo\".", + errorHandler.getMessage(0)); } /** * Tests append method under normal conditions. - * @deprecated Since setErrorHandler is deprecated */ public void testAppend() { SyslogAppender appender = new SyslogAppender(); @@ -349,8 +332,7 @@ public void testAppend() { appender.setFacility("user"); appender.setLayout(new PatternLayout("%m%n")); - org.apache.log4j.VectorErrorHandler errorHandler = - new org.apache.log4j.VectorErrorHandler(); + VectorErrorHandler errorHandler = new VectorErrorHandler(); appender.setErrorHandler(errorHandler); appender.activateOptions(); @@ -374,7 +356,7 @@ public void testAppend() { /** * Tests SyslogAppender with IPv6 address. - */ + */ public void testIPv6() { SyslogAppender appender = new SyslogAppender(); appender.setSyslogHost("::1"); @@ -382,7 +364,7 @@ public void testIPv6() { /** * Tests SyslogAppender with IPv6 address enclosed in square brackets. - */ + */ public void testIPv6InBrackets() { SyslogAppender appender = new SyslogAppender(); appender.setSyslogHost("[::1]"); @@ -391,7 +373,7 @@ public void testIPv6InBrackets() { /** * Tests SyslogAppender with IPv6 address enclosed in square brackets * followed by port specification. - */ + */ public void testIPv6AndPort() { SyslogAppender appender = new SyslogAppender(); appender.setSyslogHost("[::1]:1514"); @@ -400,74 +382,304 @@ public void testIPv6AndPort() { /** * Tests SyslogAppender with host name enclosed in square brackets * followed by port specification. - */ + */ public void testHostNameAndPort() { SyslogAppender appender = new SyslogAppender(); appender.setSyslogHost("localhost:1514"); } + /** * Tests SyslogAppender with IPv4 address followed by port specification. - */ + */ public void testIPv4AndPort() { SyslogAppender appender = new SyslogAppender(); appender.setSyslogHost("127.0.0.1:1514"); } - - private String toString(DatagramPacket p){ - return new String(p.getData(), 0, p.getLength()); + + /** + * Tests SyslogAppender with setTag. + */ + public void testTag() { + SyslogAppender appender = new SyslogAppender(); + appender.setTag("testtag"); + assertEquals("testtag", appender.getTag()); } - - public void testActualLogging() throws Exception { - SyslogAppender appender = new SyslogAppender(); - appender.setSyslogHost("localhost:" + ds.getLocalPort()); - appender.setName("name"); - PatternLayout pl = new PatternLayout("%m"); - pl.setFooter("EOF"); - appender.setLayout(pl); - appender.activateOptions(); - - Logger l = Logger.getRootLogger(); - l.addAppender(appender); - l.info("greetings"); - ds.receive(p); - String s = toString(p); - StringTokenizer st = new StringTokenizer(s, "<>() "); - assertEquals("14", st.nextToken()); - assertEquals(3, st.nextToken().length()); - st.nextToken(); // date - st.nextToken(); // time - assertEquals(appender.getLocalHostname(), st.nextToken()); - assertEquals("greetings", st.nextToken()); + + /** + * Tests SyslogAppender with null tag. + */ + public void testNullTag() { + SyslogAppender appender = new SyslogAppender(); + appender.setTag(null); + assertNull(appender.getTag()); } - - public void testLoggingHeaderFooter() throws Exception { - SyslogAppender appender = new SyslogAppender(); - appender.setSyslogHost("localhost:" + ds.getLocalPort()); - appender.setName("name"); - PatternLayout pl = new PatternLayout("%m"); - pl.setHeader("HI"); - pl.setFooter("BYE"); - appender.setLayout(pl); - appender.activateOptions(); - ds.receive(p); - String s = toString(p); - assertEquals(true, s.endsWith("HI")); - - appender.close(); - ds.receive(p); - s = toString(p); - assertEquals(true, s.endsWith("BYE")); + /** + * Tests SyslogAppender with long tag. + */ + public void testLongTag() { + SyslogAppender appender = new SyslogAppender(); + appender.setTag("testtagtesttagtesttagtesttagtesttag"); + assertEquals(appender.getTag(), "testtagtesttagtesttagtesttagtest"); } - - public void testLeak() throws IOException { - DatagramSocket ds = new DatagramSocket(); - for (int i = 0; i < 100; i++) { - SyslogWriter sw = new SyslogWriter("localhost:" + ds.getLocalPort()); - sw.close(); - } - ds.close(); + + /** + * Tests SyslogAppender with non alnum tag. + */ + public void testNonAlnumTag() { + SyslogAppender appender = new SyslogAppender(); + try{ + appender.setTag("testtag testtag"); + fail("SyslogAppender.setTag() should have thrown an exception."); + } catch (IllegalArgumentException e) { + // Correct behavior, ignore and let the test pass. + } } - + + private static String[] log(final boolean header, + final String tag, + final String msg, + final Exception ex, + final int packets) throws Exception { + DatagramSocket ds = new DatagramSocket(); + ds.setSoTimeout(2000); + + SyslogAppender appender = new SyslogAppender(); + appender.setSyslogHost("localhost:" + ds.getLocalPort()); + appender.setName("name"); + appender.setHeader(header); + appender.setTag(tag); + PatternLayout pl = new PatternLayout("%m"); + appender.setLayout(pl); + appender.activateOptions(); + + Logger l = Logger.getRootLogger(); + l.addAppender(appender); + if (ex == null) { + l.info(msg); + } else { + l.error(msg, ex); + } + appender.close(); + String[] retval = new String[packets]; + byte[] buf = new byte[1000]; + for(int i = 0; i < packets; i++) { + DatagramPacket p = new DatagramPacket(buf, 0, buf.length); + ds.receive(p); + retval[i] = new String(p.getData(), 0, p.getLength()); + } + ds.close(); + return retval; + } + + public void testActualLogging() throws Exception { + String s = log(false, null, "greetings", null, 1)[0]; + StringTokenizer st = new StringTokenizer(s, "<>() "); + assertEquals("14", st.nextToken()); + assertEquals("greetings", st.nextToken()); + } + + /** + * Exception with printStackTrace that breaks earlier SyslogAppender. + */ + private static class MishandledException extends Exception { + private static final long serialVersionUID = 1L; + /* + * Create new instance. + */ + public MishandledException() { + } + + /** + * Print stack trace. + * @param w print writer, may not be null. + */ + public void printStackTrace(final java.io.PrintWriter w) { + w.println("Mishandled stack trace follows:"); + w.println(""); + w.println("No tab here"); + w.println("\ttab here"); + w.println("\t"); + } + } + + /** + * Tests fix for bug 40502. + * @throws Exception on IOException. + */ + public void testBadTabbing() throws Exception { + String[] s = log(false, null, "greetings", new MishandledException(), 6); + StringTokenizer st = new StringTokenizer(s[0], "<>() "); + assertEquals("11", st.nextToken()); + assertEquals("greetings", st.nextToken()); + assertEquals("<11>Mishandled stack trace follows:", s[1]); + assertEquals("<11>", s[2]); + assertEquals("<11>No tab here", s[3]); + assertEquals("<11>" + SyslogAppender.TAB + "tab here", s[4]); + assertEquals("<11>" + SyslogAppender.TAB, s[5]); + } + + /** + * Tests presence of timestamp if header = true. + * + * @throws Exception if IOException. + */ + public void testHeaderLogging() throws Exception { + Date preDate = new Date(); + String s = log(true, null, "greetings", null, 1)[0]; + Date postDate = new Date(); + assertEquals("<14>", s.substring(0, 4)); + + String syslogDateStr = s.substring(4, 20); + SimpleDateFormat fmt = new SimpleDateFormat("MMM dd HH:mm:ss ", Locale.ENGLISH); + Date syslogDate = fmt.parse(syslogDateStr); + Calendar cal = Calendar.getInstance(Locale.ENGLISH); + cal.setTime(syslogDate); + int syslogMonth = cal.get(Calendar.MONTH); + int syslogDay = cal.get(Calendar.DATE); + if (syslogDay < 10) { + assertEquals(' ', syslogDateStr.charAt(4)); + } + cal.setTime(preDate); + int preMonth = cal.get(Calendar.MONTH); + cal.set(Calendar.MILLISECOND, 0); + preDate = cal.getTime(); + int syslogYear; + if (preMonth == syslogMonth) { + syslogYear = cal.get(Calendar.YEAR); + } else { + cal.setTime(postDate); + syslogYear = cal.get(Calendar.YEAR); + } + cal.setTime(syslogDate); + cal.set(Calendar.YEAR, syslogYear); + syslogDate = cal.getTime(); + assertTrue(syslogDate.compareTo(preDate) >= 0); + assertTrue(syslogDate.compareTo(postDate) <= 0); + } + + + /** + * Tests presence of tag if set + */ + public void testHeaderTagLogging() throws Exception { + String s = log(true, "testtag", "greetings", null, 1)[0]; + assertEquals("<14>", s.substring(0, 4)); + + StringTokenizer st = new StringTokenizer(s.substring(21), " "); + + // Throw away the hostname + st.nextToken(); + + assertEquals("testtag:", st.nextToken()); + } + + /** + * Tests presence of tag on every line of the exception + */ + public void testHeaderTagExceptionLogging() throws Exception { + String[] s = log(true, "testtag", "greetings", new Exception(), 6); + for(int i=0; i < s.length; i++) { + System.err.println(s[i]); + assertEquals("<11>", s[i].substring(0, 4)); + StringTokenizer st = new StringTokenizer(s[i].substring(21), " "); + // Throw away the hostname + st.nextToken(); + assertEquals("testtag:", st.nextToken()); + } + } + + /** + * Tests absesence of tag if set to null + */ + public void testHeaderNullTagLogging() throws Exception { + String s = log(true, null, "greetings", null, 1)[0]; + assertEquals("<14>", s.substring(0, 4)); + + StringTokenizer st = new StringTokenizer(s.substring(21), " "); + + // Throw away the hostname + st.nextToken(); + + assertEquals("greetings", st.nextToken()); + } + + /** + * Tests that any header or footer in layout is sent. + * @throws Exception if exception during test. + */ + public void testLayoutHeader() throws Exception { + DatagramSocket ds = new DatagramSocket(); + ds.setSoTimeout(2000); + + SyslogAppender appender = new SyslogAppender(); + appender.setSyslogHost("localhost:" + ds.getLocalPort()); + appender.setName("name"); + appender.setHeader(false); + HTMLLayout pl = new HTMLLayout(); + appender.setLayout(pl); + appender.activateOptions(); + + Logger l = Logger.getRootLogger(); + l.addAppender(appender); + l.info("Hello, World"); + appender.close(); + String[] s = new String[3]; + byte[] buf = new byte[1000]; + for(int i = 0; i < 3; i++) { + DatagramPacket p = new DatagramPacket(buf, 0, buf.length); + ds.receive(p); + s[i] = new String(p.getData(), 0, p.getLength()); + } + ds.close(); + assertEquals("<14>", s[2].substring(0,12)); + } + + /** + * Tests that syslog packets do not exceed 1024 bytes. + * See bug 42087. + * @throws Exception if exception during test. + */ + public void testBigPackets() throws Exception { + DatagramSocket ds = new DatagramSocket(); + ds.setSoTimeout(2000); + + SyslogAppender appender = new SyslogAppender(); + appender.setSyslogHost("localhost:" + ds.getLocalPort()); + appender.setName("name"); + appender.setHeader(false); + PatternLayout pl = new PatternLayout("%m"); + appender.setLayout(pl); + appender.activateOptions(); + + Logger l = Logger.getRootLogger(); + l.addAppender(appender); + StringBuffer msgbuf = new StringBuffer(); + while(msgbuf.length() < 8000) { + msgbuf.append("0123456789"); + } + String msg = msgbuf.toString(); + l.info(msg); + appender.close(); + String[] s = new String[8]; + byte[] buf = new byte[1200]; + for(int i = 0; i < 8; i++) { + DatagramPacket p = new DatagramPacket(buf, 0, buf.length); + ds.receive(p); + assertTrue(p.getLength() <= 1024); + s[i] = new String(p.getData(), 0, p.getLength()); + } + ds.close(); + StringBuffer rcvbuf = new StringBuffer(s[0]); + rcvbuf.delete(0, 4); + for(int i = 1; i < 8; i++) { + rcvbuf.setLength(rcvbuf.length() - 3); + rcvbuf.append(s[i].substring(s[i].indexOf("...") + 3)); + } + assertEquals(msg.length(), rcvbuf.length()); + assertEquals(msg, rcvbuf.toString()); + } + } diff --git a/tests/src/java/org/apache/log4j/net/TelnetAppenderTest.java b/tests/src/java/org/apache/log4j/net/TelnetAppenderTest.java index 0896d5d84f..d5a1e0f75e 100644 --- a/tests/src/java/org/apache/log4j/net/TelnetAppenderTest.java +++ b/tests/src/java/org/apache/log4j/net/TelnetAppenderTest.java @@ -1,58 +1,78 @@ -package org.apache.log4j.net; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.Socket; - -import org.apache.log4j.Logger; -import org.apache.log4j.PatternLayout; - -import junit.framework.TestCase; - -public class TelnetAppenderTest extends TestCase { - - int port = 54353; - ByteArrayOutputStream bo = new ByteArrayOutputStream(); - - public class ReadThread extends Thread { - public void run() { - try { - Socket s = new Socket("localhost", port); - InputStream i = s.getInputStream(); - while (!Thread.interrupted()) { - int c = i.read(); - if (c == -1) - break; - bo.write(c); - } - s.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - public void testIt() throws Exception { - int oldActive = Thread.activeCount(); - TelnetAppender ta = new TelnetAppender(); - ta.setName("ta"); - ta.setPort(port); - ta.setLayout(new PatternLayout("%p - %m")); - ta.activateOptions(); - Logger l = Logger.getLogger("x"); - l.addAppender(ta); - Thread t = new ReadThread(); - t.start(); - Thread.sleep(200); - l.info("hi"); - ta.close(); - Thread.sleep(200); - t.interrupt(); - t.join(); - String s = bo.toString(); - assertEquals(true, s.endsWith("INFO - hi")); - assertEquals(oldActive, Thread.activeCount()); - } - -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.net; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.Socket; + +import org.apache.log4j.Logger; +import org.apache.log4j.PatternLayout; + +import junit.framework.TestCase; + +public class TelnetAppenderTest extends TestCase { + + int port = 54353; + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + + public class ReadThread extends Thread { + public void run() { + try { + Socket s = new Socket("localhost", port); + InputStream i = s.getInputStream(); + while (!Thread.interrupted()) { + int c = i.read(); + if (c == -1) { + break; + } + bo.write(c); + } + s.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public void testIt() throws Exception { + int oldActive = Thread.activeCount(); + TelnetAppender ta = new TelnetAppender(); + ta.setName("ta"); + ta.setPort(port); + ta.setLayout(new PatternLayout("%p - %m")); + ta.activateOptions(); + Logger l = Logger.getLogger("x"); + l.addAppender(ta); + Thread t = new ReadThread(); + t.start(); + Thread.sleep(200); + l.info("hi"); + Thread.sleep(1000); + ta.close(); + Thread.sleep(200); + t.interrupt(); + t.join(); + String s = bo.toString(); + assertTrue(s.endsWith("INFO - hi")); + if(System.getProperty("java.vendor").indexOf("Free") == -1) { + assertEquals(oldActive, Thread.activeCount()); + } + } + +} diff --git a/tests/src/java/org/apache/log4j/net/XMLDecoderTest.java b/tests/src/java/org/apache/log4j/net/XMLDecoderTest.java deleted file mode 100644 index cbebd7b3c4..0000000000 --- a/tests/src/java/org/apache/log4j/net/XMLDecoderTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Created on 29/04/2003 - * - * To change the template for this generated file go to - * Window>Preferences>Java>Code Generation>Code and Comments - */ -package org.apache.log4j.net; - -import java.io.File; -import java.util.List; - -import junit.framework.TestCase; - -import org.apache.log4j.xml.XMLDecoder; - -/** - * @author Paul Smith - * - */ -public class XMLDecoderTest extends TestCase { - - /** - * Constructor for XMLDecoderTest. - * @param arg0 - */ - public XMLDecoderTest(String arg0) { - super(arg0); - } - - /* - * Test for Vector decode(File) - */ - public void testDecodeFile() throws Exception { - XMLDecoder xmlDecoder = new XMLDecoder(); - List events = xmlDecoder.decode(new File("tests/witness/eventSet.1.xml").toURL()); - assertTrue("Should have returned at least 418 events: " + events.size(), events.size()==418); - - } - -} diff --git a/tests/src/java/org/apache/log4j/nt/NTEventLogAppenderTest.java b/tests/src/java/org/apache/log4j/nt/NTEventLogAppenderTest.java index 1c19b9f15e..bba8de0602 100755 --- a/tests/src/java/org/apache/log4j/nt/NTEventLogAppenderTest.java +++ b/tests/src/java/org/apache/log4j/nt/NTEventLogAppenderTest.java @@ -1,12 +1,13 @@ /* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,13 +16,11 @@ */ package org.apache.log4j.nt; - import junit.framework.TestCase; - -import org.apache.log4j.BasicConfigurator; -import org.apache.log4j.Level; -import org.apache.log4j.LogManager; import org.apache.log4j.Logger; +import org.apache.log4j.LogManager; +import org.apache.log4j.Level; +import org.apache.log4j.BasicConfigurator; /** @@ -31,6 +30,7 @@ * @author Curt Arnold */ public class NTEventLogAppenderTest extends TestCase { + /** * Clean up configuration after each test. */ @@ -43,15 +43,13 @@ public void tearDown() { */ public void testSimple() { BasicConfigurator.configure(new NTEventLogAppender()); - - Logger logger = - Logger.getLogger("org.apache.log4j.nt.NTEventLogAppenderTest"); - int i = 0; - logger.debug("Message " + i++); - logger.info("Message " + i++); - logger.warn("Message " + i++); - logger.error("Message " + i++); + Logger logger = Logger.getLogger("org.apache.log4j.nt.NTEventLogAppenderTest"); + int i = 0; + logger.debug( "Message " + i++); + logger.info( "Message " + i++); + logger.warn( "Message " + i++); + logger.error( "Message " + i++); logger.log(Level.FATAL, "Message " + i++); - logger.debug("Message " + i++, new Exception("Just testing.")); + logger.debug("Message " + i++, new Exception("Just testing.")); } } diff --git a/tests/src/java/org/apache/log4j/or/ORTestCase.java b/tests/src/java/org/apache/log4j/or/ORTestCase.java index f846f42ce3..b7287d856c 100644 --- a/tests/src/java/org/apache/log4j/or/ORTestCase.java +++ b/tests/src/java/org/apache/log4j/or/ORTestCase.java @@ -15,20 +15,20 @@ * limitations under the License. */ - // // Log4j uses the JUnit framework for internal unit testing. JUnit // available from // // http://www.junit.org + + package org.apache.log4j.or; -import junit.framework.Test; + + import junit.framework.TestCase; import junit.framework.TestSuite; - -import org.apache.log4j.or.ObjectRenderer; -import org.apache.log4j.or.RendererMap; +import junit.framework.Test; import java.io.Serializable; @@ -38,25 +38,31 @@ @author Ceki Gülcü @since 1.0 */ public class ORTestCase extends TestCase { + static UTObjectRenderer aor; static UTObjectRenderer bor; static UTObjectRenderer xor; static UTObjectRenderer yor; + static UTObjectRenderer oor; static UTObjectRenderer nor; static UTObjectRenderer ior; static UTObjectRenderer cor; static UTObjectRenderer sor; + + public ORTestCase(String name) { super(name); } - public void setUp() { + + public + void setUp() { aor = new UTObjectRenderer("A"); bor = new UTObjectRenderer("B"); - xor = new UTObjectRenderer("X"); - yor = new UTObjectRenderer("Y"); + xor = new UTObjectRenderer("X"); + yor = new UTObjectRenderer("Y"); oor = new UTObjectRenderer("Object"); nor = new UTObjectRenderer("Number"); @@ -67,7 +73,8 @@ public void setUp() { // Add: no renderer // Expect: defaultRenderer - public void test1() { + public + void test1() { RendererMap map = new RendererMap(); ObjectRenderer dr = map.getDefaultRenderer(); ObjectRenderer r = map.get(Integer.class); @@ -76,37 +83,39 @@ public void test1() { // Add: Integer renderer // Expect: Integer renderer - public void test2() { + public + void test2() { RendererMap map = new RendererMap(); map.put(Integer.class, ior); - ObjectRenderer r = map.get(Integer.class); assertEquals(r, ior); + } // Add: Number renderer // Expect: Number - public void test3() { + public + void test3() { RendererMap map = new RendererMap(); map.put(Number.class, ior); - ObjectRenderer r = map.get(Integer.class); assertEquals(r, ior); } // Add: Object renderer // Result: Object - public void test4() { + public + void test4() { RendererMap map = new RendererMap(); map.put(Object.class, oor); - ObjectRenderer r = map.get(Integer.class); assertEquals(r, oor); } // Add: Object, Number, Integer // Expect: Integer - public void test5() { + public + void test5() { RendererMap map = new RendererMap(); map.put(Object.class, oor); @@ -119,57 +128,71 @@ public void test5() { // Add: Object, Number // Expect: Number - public void test6() { + public + void test6() { RendererMap map = new RendererMap(); map.put(Object.class, oor); map.put(Number.class, nor); - + ObjectRenderer r = map.get(Integer.class); assertEquals(r, nor); } // Add: Comparable // Expect: Comparable - public void test7() { + public + void test7() throws Exception { RendererMap map = new RendererMap(); - map.put(Comparable.class, cor); - + Class comparable = null; + try { + comparable = Class.forName("java.lang.Comparable"); + } catch(Exception ex) { + // likely JDK 1.1 + return; + } + map.put(comparable, cor); ObjectRenderer r = map.get(Integer.class); assertEquals(r, cor); } + // Add: Serializable // Expect: Serializablee - public void test8() { + public + void test8() { RendererMap map = new RendererMap(); - map.put(Serializable.class, sor); - + map.put(Serializable.class, sor); ObjectRenderer r = map.get(Integer.class); assertEquals(r, sor); } // Add: Y // Expect: Y - public void test9() { + public + void test9() { RendererMap map = new RendererMap(); - map.put(Y.class, yor); - + map.put(Y.class, yor); ObjectRenderer r = map.get(B.class); assertEquals(r, yor); } // Add: X // Expect: X - public void test10() { + public + void test10() { RendererMap map = new RendererMap(); - map.put(X.class, xor); - + map.put(X.class, xor); ObjectRenderer r = map.get(B.class); assertEquals(r, xor); } - public static Test suite() { + + + + public + static + Test suite() { TestSuite suite = new TestSuite(); suite.addTest(new ORTestCase("test1")); suite.addTest(new ORTestCase("test2")); @@ -181,40 +204,42 @@ public static Test suite() { suite.addTest(new ORTestCase("test8")); suite.addTest(new ORTestCase("test9")); suite.addTest(new ORTestCase("test10")); - return suite; } -} + +} + class UTObjectRenderer implements ObjectRenderer { + String name; UTObjectRenderer(String name) { this.name = name; } - public String doRender(Object o) { + public + String doRender(Object o) { return name; } - public String toString() { - return ("UTObjectRenderer: " + name); + public + String toString() { + return("UTObjectRenderer: "+name); } } -interface X { +interface X { } - interface Y extends X { } -class A implements Y { +class A implements Y { } - -class B extends A { +class B extends A { } diff --git a/tests/src/java/org/apache/log4j/pattern/CachedDateFormatTest.java b/tests/src/java/org/apache/log4j/pattern/CachedDateFormatTest.java index e2e15a9a75..2ad4cdfb67 100644 --- a/tests/src/java/org/apache/log4j/pattern/CachedDateFormatTest.java +++ b/tests/src/java/org/apache/log4j/pattern/CachedDateFormatTest.java @@ -33,7 +33,7 @@ /** Unit test {@link AbsoluteTimeDateFormat}. @author Curt Arnold - @since 1.3.0 */ + */ public final class CachedDateFormatTest extends TestCase { @@ -51,21 +51,6 @@ private static DateFormat createAbsoluteTimeDateFormat(TimeZone timeZone) { return df; } - /** - * Asserts that formatting the provided date results - * in the expected string. - * - * @param date Date date - * @param timeZone TimeZone timezone for conversion - * @param expected String expected string - */ - private final void assertFormattedTime(Date date, - TimeZone timeZone, - String expected) { - DateFormat formatter = createAbsoluteTimeDateFormat(timeZone); - String actual = formatter.format(date); - assertEquals(expected, actual); - } /** * Timezone representing GMT. @@ -149,8 +134,8 @@ public void test4() { Date jul1 = new Date(ticks); assertEquals(baseFormat.format(jul1), cachedFormat.format(jul1)); Date plus8ms = new Date(ticks + 8); - String base = baseFormat.format(plus8ms); - String cached = cachedFormat.format(plus8ms); + baseFormat.format(plus8ms); + cachedFormat.format(plus8ms); assertEquals(baseFormat.format(plus8ms), cachedFormat.format(plus8ms)); Date plus17ms = new Date(ticks + 17); assertEquals(baseFormat.format(plus17ms), cachedFormat.format(plus17ms)); @@ -240,15 +225,17 @@ public void test9() { c.set(Calendar.MILLISECOND, 23); c.setTimeZone(cet); + String expected = baseFormat.format(c.getTime()); String s = cachedFormat.format(c.getTime()); - assertEquals("2004-December-12 20:00:37,23 GMT+01:00", s); + assertEquals(expected, s); c.set(2005, Calendar.JANUARY, 1, 0, 0); c.set(Calendar.SECOND, 13); c.set(Calendar.MILLISECOND, 905); + expected = baseFormat.format(c.getTime()); s = cachedFormat.format(c.getTime()); - assertEquals("2005-January-01 00:00:13,905 GMT+01:00", s); + assertEquals(expected, s); } @@ -267,18 +254,21 @@ public void test10() { c.set(Calendar.MILLISECOND, 23); c.setTimeZone(cet); + String expected = baseFormat.format(c.getTime()); String s = cachedFormat.format(c.getTime()); - assertEquals("October 023 Tuesday", s); + assertEquals(expected, s); c.set(2004, Calendar.NOVEMBER, 1, 0, 0); c.set(Calendar.MILLISECOND, 23); + expected = baseFormat.format(c.getTime()); s = cachedFormat.format(c.getTime()); - assertEquals("November 023 Monday", s); + assertEquals(expected, s); c.set(Calendar.MILLISECOND, 984); + expected = baseFormat.format(c.getTime()); s = cachedFormat.format(c.getTime()); - assertEquals("November 984 Monday", s); + assertEquals(expected, s); } /** @@ -291,21 +281,25 @@ public void test11() { // String badPattern = "ss,SS0"; SimpleDateFormat simpleFormat = new SimpleDateFormat(badPattern); + SimpleDateFormat baseFormat = new SimpleDateFormat(badPattern); DateFormat gmtFormat = new CachedDateFormat(simpleFormat, 1000); gmtFormat.setTimeZone(GMT); + baseFormat.setTimeZone(GMT); // // The first request has to 100 ms after an ordinal second // to push the literal zero out of the pattern check long ticks = 11142L * 86400000L; Date jul2 = new Date(ticks + 120); - assertEquals("00,1200", gmtFormat.format(jul2)); + String expected = baseFormat.format(jul2); + assertEquals(expected, gmtFormat.format(jul2)); jul2.setTime(ticks + 87); // // Cache gives 00,087 - assertEquals("00,870", gmtFormat.format(jul2)); + expected = baseFormat.format(jul2); + assertEquals(expected, gmtFormat.format(jul2)); } diff --git a/tests/src/java/org/apache/log4j/pattern/FormattingInfoTest.java b/tests/src/java/org/apache/log4j/pattern/FormattingInfoTest.java index d9d5d14e4d..be39cde846 100644 --- a/tests/src/java/org/apache/log4j/pattern/FormattingInfoTest.java +++ b/tests/src/java/org/apache/log4j/pattern/FormattingInfoTest.java @@ -24,7 +24,6 @@ * Tests for FormattingInfo. * * @author Curt Arnold - * @since 1.3 * */ public class FormattingInfoTest extends TestCase { diff --git a/tests/src/java/org/apache/log4j/pattern/NameAbbreviatorTest.java b/tests/src/java/org/apache/log4j/pattern/NameAbbreviatorTest.java index f143fef210..7ced8f53ed 100644 --- a/tests/src/java/org/apache/log4j/pattern/NameAbbreviatorTest.java +++ b/tests/src/java/org/apache/log4j/pattern/NameAbbreviatorTest.java @@ -23,9 +23,6 @@ /** * Tests for NameAbbrevator. * - * @author Curt Arnold - * @since 1.3 - * */ public class NameAbbreviatorTest extends TestCase { /** @@ -301,4 +298,39 @@ public void testMulti() { abbrev.abbreviate(fieldStart, buf); assertEquals("DEBUG - .", buf.toString()); } + + /** + * Check that getAbbreviator("-1").abbreviate() drops first name element. + * + */ + public void testMinusOne() { + NameAbbreviator abbrev = NameAbbreviator.getAbbreviator("-1"); + StringBuffer buf = new StringBuffer("DEBUG - "); + int fieldStart = buf.length(); + buf.append("org.example.foo.bar"); + abbrev.abbreviate(fieldStart, buf); + assertEquals("DEBUG - example.foo.bar", buf.toString()); + + buf.setLength(0); + buf.append("DEBUG - "); + fieldStart = buf.length(); + buf.append("bar"); + abbrev.abbreviate(fieldStart, buf); + assertEquals("DEBUG - bar", buf.toString()); + + buf.setLength(0); + buf.append("DEBUG - "); + fieldStart = buf.length(); + abbrev.abbreviate(fieldStart, buf); + assertEquals("DEBUG - ", buf.toString()); + + buf.setLength(0); + buf.append("DEBUG - "); + fieldStart = buf.length(); + buf.append("."); + abbrev.abbreviate(fieldStart, buf); + assertEquals("DEBUG - ", buf.toString()); + + } + } diff --git a/tests/src/java/org/apache/log4j/pattern/Num343PatternConverter.java b/tests/src/java/org/apache/log4j/pattern/Num343PatternConverter.java index cc36952e67..27a58bd3c3 100644 --- a/tests/src/java/org/apache/log4j/pattern/Num343PatternConverter.java +++ b/tests/src/java/org/apache/log4j/pattern/Num343PatternConverter.java @@ -18,7 +18,6 @@ package org.apache.log4j.pattern; import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.ULogger; public class Num343PatternConverter extends LoggingEventPatternConverter { @@ -28,8 +27,7 @@ private Num343PatternConverter() { } private static final Num343PatternConverter INSTANCE = new Num343PatternConverter(); - public static PatternConverter newInstance(final String[] options, - final ULogger logger) { + public static PatternConverter newInstance(final String[] options) { return INSTANCE; } diff --git a/tests/src/java/org/apache/log4j/pattern/PatternParserTest.java b/tests/src/java/org/apache/log4j/pattern/PatternParserTest.java index 27c10d7d95..10f56cfba9 100644 --- a/tests/src/java/org/apache/log4j/pattern/PatternParserTest.java +++ b/tests/src/java/org/apache/log4j/pattern/PatternParserTest.java @@ -31,35 +31,24 @@ import org.apache.log4j.Layout; import org.apache.log4j.Level; -import org.apache.log4j.LogManager; import org.apache.log4j.Logger; -import org.apache.log4j.ULogger; -import org.apache.log4j.spi.LoggerRepository; import org.apache.log4j.spi.LoggingEvent; /** - Test case for helpers/PatternParser.java. Tests the various + Test case for PatternParser.java. Tests the various conversion patterns supported by PatternParser. This test - class tests PatternParser via the PatternLayout class which + class tests PatternParser via the EnhancedPatternLayout class which uses it. */ public class PatternParserTest extends TestCase { - Logger logger = Logger.getLogger("org.foobar"); - LoggingEvent event; - long now; - LoggerRepository repository; - + private final Logger logger = Logger.getLogger("org.foobar"); + private final LoggingEvent event; + public PatternParserTest(String name) { super(name); - repository = LogManager.getLoggerRepository(); - now = System.currentTimeMillis() + 13; - - event = new LoggingEvent(); - event.setLogger(logger); - event.setTimeStamp(now); - event.setLevel(Level.INFO); - event.setMessage("msg 1"); + event = new LoggingEvent("org.apache.log4j.Logger", + logger, Level.INFO, "msg 1", null); } private static String convert( @@ -70,8 +59,7 @@ private static String convert( List fields = new ArrayList(); PatternParser.parse(pattern, converters, fields, registry, - PatternParser.getPatternLayoutRules(), - null); + PatternParser.getPatternLayoutRules()); assertEquals(converters.size(), fields.size()); StringBuffer buf = new StringBuffer(); @@ -120,7 +108,7 @@ public void testBasic1() throws Exception { public void testBasic2() throws Exception { String result = convert("%relative %-5level [%thread] %logger - %m%n", null, event); - long expectedRelativeTime = now - LoggingEvent.getStartTime(); + long expectedRelativeTime = event.timeStamp - LoggingEvent.getStartTime(); assertEquals(expectedRelativeTime + " INFO [main] "+logger.getName()+" - msg 1" + Layout.LINE_SEP, result); } @@ -128,9 +116,9 @@ public void testMultiOption() throws Exception { String result = convert("%d{HH:mm:ss}{GMT} %d{HH:mm:ss} %c - %m", null, event); SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); - String localTime = dateFormat.format(new Date(event.getTimeStamp())); + String localTime = dateFormat.format(new Date(event.timeStamp)); dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); - String utcTime = dateFormat.format(new Date(event.getTimeStamp())); + String utcTime = dateFormat.format(new Date(event.timeStamp)); StringBuffer buf = new StringBuffer(utcTime); buf.append(' '); buf.append(localTime); @@ -162,8 +150,8 @@ public void testMalformedOption() { private void assertFactories(Map rules) throws Exception { assertTrue(rules.size() > 0); Iterator iter = rules.values().iterator(); - Class[] factorySig = new Class[] { Class.forName("[Ljava.lang.String;"), ULogger.class }; - Object[] factoryArg = new Object[] { null, null }; + Class[] factorySig = new Class[] { Class.forName("[Ljava.lang.String;") }; + Object[] factoryArg = new Object[] { null }; while(iter.hasNext()) { Class ruleClass = (Class) iter.next(); Method factory = ruleClass.getMethod("newInstance", factorySig); diff --git a/tests/src/java/org/apache/log4j/performance/GetLoggerTest.java b/tests/src/java/org/apache/log4j/performance/GetLoggerTest.java deleted file mode 100644 index 0b3d566f99..0000000000 --- a/tests/src/java/org/apache/log4j/performance/GetLoggerTest.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.performance; -import org.apache.log4j.Logger; - -/** - - This program evaluates the performance of getLogger - when creating and retrieving loggers. - - -*/ -public class GetLoggerTest { - - static - public - void main(String[] args) { - System.out.println("Usage: java org.apache.log4j.GetLoggerTest passes [nameCount nameLength]\n"); - int passes = 5; - String[] names = new String[] { "org.apache.log4j.Alpha", - "com.example.acme.Bravo", - "com.example.acme.Charlie", - "net.example.acme.Delta", - "org.apache.log4j.Echo", - "com.example.acme.Foxtrot", - "com.example.acme.Google", - "net.example.acme.Hotel", - "com.example.acme.Indigo", - "com.example.acme.Jakarta", - "net.example.acme.Kaffe", - "com.example.acme.Lima", - "com.example.acme.Mommy", - "net.example.acme.Nancy", - "com.example.acme.Opera", - "com.example.acme.Picasso", - "net.example.acme.Quebec", - "com.example.acme.Romeo", - "com.example.acme.Sierra", - "net.example.acme.Tango", - "com.example.acme.Umlat", - "com.example.acme.Victor", - "net.example.acme.Widget", - "com.example.acme.Xray", - "com.example.acme.Yellow", - "net.example.acme.Zulu"}; - if (args.length > 0) { - passes = Integer.parseInt(args[0]); - if (args.length > 1) { - String[] newNames = new String[Integer.parseInt(args[1])]; - for (int i = 0; i < newNames.length; i++) { - newNames[i] = names[i % names.length] + i; - } - if (args.length > 2) { - int nameLength = Integer.parseInt(args[2]); - StringBuffer buf = new StringBuffer(nameLength); - for (int i = 0; i < newNames.length; i++) { - buf.insert(0, newNames[i]); - buf.setLength(nameLength); - newNames[i] = buf.toString(); - } - } - names = newNames; - } - } - int sum = 0; - for (int i = 0; i < passes; i++) { - long start = System.currentTimeMillis(); - for (int j = 0; j < names.length; j++) { - Logger.getLogger(names[j]); - } - long end = System.currentTimeMillis(); - if (i != 0) { - sum += (end - start); - } - System.out.println("Pass " + i + ": " + (end - start) + " ms.\n"); - } - if (passes != 1) { - System.out.println("Average non-initial pass: " + sum / (passes - 1) + " ms.\n"); - } - } -} diff --git a/tests/src/java/org/apache/log4j/performance/LoggingLoop.java b/tests/src/java/org/apache/log4j/performance/LoggingLoop.java deleted file mode 100644 index 6e8ab482f1..0000000000 --- a/tests/src/java/org/apache/log4j/performance/LoggingLoop.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.performance; - - -import org.apache.log4j.Appender; -import org.apache.log4j.Level; -import org.apache.log4j.Logger; - - - -/** - * Logs in a loop a number of times and measure the elapsed time. - * - * @author Ceki Gülcü - */ -public class LoggingLoop { - static int runLength; - static int command; - static final Logger logger = Logger.getLogger(LoggingLoop.class); - static final double MILLION = 1000 * 1000.0; - static final int WARM = 1000 * 100; - static final int ALL = 0; - static final int NOLOG_BAD = 1; - static final int NOLOG_BETTER = 2; - static final int NOLOG_NOPARAM = 3; - static final int LOG_BAD = 4; - static final int LOG_BETTER = 5; - static final int LOG_NOPARAM = 6; - - public static void main(String[] args) throws Exception { - Logger root = Logger.getRootLogger(); - - if (args.length == 2) { - init(args[0], args[1]); - } else { - usage("Wrong number of arguments."); - } - - switch(command) { - case ALL: - case NOLOG_BAD: - root.setLevel(Level.OFF); - loopBad(); - if(command != ALL) break; - case NOLOG_BETTER: - root.setLevel(Level.OFF); - loopBetter(); - if(command != ALL) break; - case NOLOG_NOPARAM: - root.setLevel(Level.OFF); - loopNoParam(); - if(command != ALL) break; - case LOG_BAD: - setNullAppender(); -// loopBad(); - if(command != ALL) break; - case LOG_BETTER: - setNullAppender(); -// loopBetter(); - if(command != ALL) break; - case LOG_NOPARAM: - setNullAppender(); -// loopNoParam(); - if(command != ALL) break; - } - System.out.println("Done."); - } - - static void usage(String msg) { - System.err.println(msg); - System.err.println( - "Usage: java " + LoggingLoop.class.getName() + " runLength configFile"); - System.err.println("\trunLength (integer) is the length of test loop."); - - System.exit(1); - } - - static void init(String runLengthStr, String commandStr) - throws Exception { - runLength = Integer.parseInt(runLengthStr); - if ("nolog-bad".equalsIgnoreCase(commandStr)) { - command = NOLOG_BAD; - } else if ("nolog-better".equalsIgnoreCase(commandStr)) { - command = NOLOG_BETTER; - } else if ("nolog-noparam".equalsIgnoreCase(commandStr)) { - command = NOLOG_NOPARAM; - } else if ("log-bad".equalsIgnoreCase(commandStr)) { - command = LOG_BAD; - } else if ("log-better".equalsIgnoreCase(commandStr)) { - command = LOG_BETTER; - } else if ("log-noparam".equalsIgnoreCase(commandStr)) { - command = LOG_NOPARAM; - } else if ("all".equalsIgnoreCase(commandStr)) { - command = ALL; - } - } - - static void setNullAppender() throws Exception { - Appender na = new NullAppender(); - //ConsoleAppender na = new ConsoleAppender(new PatternLayout()); - //Appender na = new FileAppender(new PatternLayout(), "toto.log"); - Logger root = Logger.getRootLogger(); - root.removeAllAppenders(); - root.addAppender(na); - root.setLevel(Level.DEBUG); - } - - static void loopBad() { - Integer x = new Integer(10); - for (int i = 0; i < WARM; i++) { - logger.debug("Entry number: {} is {}.", new Object[]{x, x}); - //logger.debug("Entry number: {} is {}.", new Object[]{new Integer(i), x}); - //logger.debug("Entry number: {} is {}.", new Object[]{new Integer(i), new Integer(i)}); - } - - Runtime.getRuntime().gc(); - long before = System.currentTimeMillis(); - for (int i = 0; i < runLength; i++) { - logger.debug("Entry number: {} is {}.", new Object[]{x, x}); - ///logger.debug("Entry number: {} is {}.", new Object[]{new Integer(i), x}); - //logger.debug("Entry number: {} is {}.", new Object[]{new Integer(i), new Integer(i)}); - } - long elapsedTime = System.currentTimeMillis() - before; - - double average = (elapsedTime * MILLION) / runLength; - System.out.println( - "Bad loop completed in [" + elapsedTime + "] milliseconds, or [" - + average + "] nanoseconds per log."); - } - - static void loopBetter() { - Integer x = new Integer(5); - for (int i = 0; i < WARM; i++) { - //logger.debug("Entry number: {} is {}.", x, x); - logger.debug("Entry number: {} is {}.", x, new Integer(i)); - //logger.debug("Entry number: {} is {}.", new Integer(i), new Integer(i)); - } - Runtime.getRuntime().gc(); - long before = System.currentTimeMillis(); - for (int i = 0; i < runLength; i++) { - //logger.debug("Entry number: {} is {}.", x, x); - logger.debug("Entry number: {} is {}.", x, new Integer(i)); - //logger.debug("Entry number: {} is {}.", new Integer(i), new Integer(i)); - } - long elapsedTime = System.currentTimeMillis() - before; - double average = (elapsedTime * MILLION) / runLength; - System.out.println( - "Better loop completed in [" + elapsedTime + "] milliseconds, or [" - + average + "] nanoseconds per log."); - } - - static void loopNoParam() { - String msg = "Some message of medium length."; - - Runtime.getRuntime().gc(); - long before = System.currentTimeMillis(); - for (int i = 0; i < runLength; i++) { - logger.debug(msg); - } - long elapsedTime = System.currentTimeMillis() - before; - double average = (elapsedTime * MILLION) / runLength; - System.out.println( - "No parameter loop completed in [" + elapsedTime - + "] milliseconds, or [" + average + "] nanoseconds per log."); - } -} \ No newline at end of file diff --git a/tests/src/java/org/apache/log4j/performance/Loop.java b/tests/src/java/org/apache/log4j/performance/Loop.java deleted file mode 100644 index 9e33051490..0000000000 --- a/tests/src/java/org/apache/log4j/performance/Loop.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.performance; - -import org.apache.log4j.ConsoleAppender; -import org.apache.log4j.Level; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.PatternLayout; -import org.apache.log4j.joran.JoranConfigurator; - - -/** - * Logs in a loop a number of times and measure the elapsed time. - * - * @author Ceki Gülcü - */ -public class Loop { - static int runLength; - static final Logger logger = Logger.getLogger(Loop.class); - - public static void main(String[] args) throws Exception { - Logger j = Logger.getLogger("org.apache.log4j.joran"); - j.setAdditivity(false); - j.setLevel(Level.WARN); - ConsoleAppender a = new ConsoleAppender(); - a.setLayout(new PatternLayout("%d %level %c - %m%n")); - a.setName("console"); - a.activateOptions(); - j.addAppender(a); - - if (args.length == 2) { - init(args[0], args[1]); - } else { - usage("Wrong number of arguments."); - } - - //memPrint(); - loop(1000, logger, "Some fix message of medium length."); - //memPrint(); - - long res = loop(runLength, logger, "Some fix message of medium length."); - double average = (res * 1000.0) / runLength; - System.out.println( - "Loop completed in [" + res + "] milliseconds, or [" + average - + "] microseconds per log."); - - //memPrint(); - } - - static void usage(String msg) { - System.err.println(msg); - System.err.println( - "Usage: java " + Loop.class.getName() + " runLength configFile"); - System.err.println("\trunLength (integer) is the length of test loop."); - System.err.println("\tconfigFile is an XML configuration file"); - - System.exit(1); - } - - static void memPrint() { - Runtime runtime = Runtime.getRuntime(); - long total = runtime.totalMemory(); - long free = runtime.freeMemory(); - long used = total - free; - System.out.println( - "Total: " + total + ", free: " + free + ", used: " + used); - } - - static void init(String runLengthStr, String configFile) - throws Exception { - runLength = Integer.parseInt(runLengthStr); - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure(configFile, LogManager.getLoggerRepository()); - } - - static long loop(long len, Logger logger, String msg) { - long before = System.currentTimeMillis(); - for (int i = 0; i < len; i++) { - logger.debug(msg); - //if(i == 1000) { - //memPrint(); - //} - } - return (System.currentTimeMillis() - before); - } -} diff --git a/tests/src/java/org/apache/log4j/performance/package.html b/tests/src/java/org/apache/log4j/performance/package.html deleted file mode 100644 index e57b59e1f6..0000000000 --- a/tests/src/java/org/apache/log4j/performance/package.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - -

    Package to measure the performance of the different log4j - components. -

    - -

    The - org.apache.log4j.performance package is intended - for internal use only. Consequently, the classes in this - package are not included in the log4j.jar file. -

    - - - diff --git a/tests/src/java/org/apache/log4j/plugins/PluginTestCase.java b/tests/src/java/org/apache/log4j/plugins/PluginTestCase.java deleted file mode 100644 index 45a397bf63..0000000000 --- a/tests/src/java/org/apache/log4j/plugins/PluginTestCase.java +++ /dev/null @@ -1,628 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.plugins; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.apache.log4j.FileAppender; -import org.apache.log4j.Hierarchy; -import org.apache.log4j.Level; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.SimpleLayout; -import org.apache.log4j.spi.LoggerRepository; -import org.apache.log4j.spi.LoggerRepositoryEx; -import org.apache.log4j.spi.RootLogger; -import org.apache.log4j.util.Compare; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; - -import java.io.File; -import java.io.IOException; - -import java.util.HashMap; - - -public class PluginTestCase extends TestCase { - - static String FILE = "output/plugins.PluginTestCase"; - static String WITNESS = "witness/plugins.PluginTestCase"; - private static boolean verbosePluginOutput = true; - private static HashMap repositoryMap = new HashMap(); - - PluginRegistry pluginRegistry; - public PluginTestCase(String name) { - super(name); - } - - public void setUp() { - pluginRegistry = ((LoggerRepositoryEx) LogManager.getLoggerRepository()).getPluginRegistry(); - - // delete the output file if they happen to exist - File file = new File(getOutputFile("test1")); - file.delete(); - file = new File(getOutputFile("test2")); - file.delete(); - } - - private String getOutputFile(String caseName) { - - return FILE + "." + caseName + ".txt"; - } - - private String getWitnessFile(String caseName) { - - return WITNESS + "." + caseName + ".txt"; - } - - private void setupAppender(String caseName) throws IOException { - - Logger root = Logger.getRootLogger(); - root.removeAllAppenders(); - - // set up appender - FileAppender appender = new FileAppender(new SimpleLayout(), - getOutputFile(caseName), false); - - //FileAppender appender = new FileAppender(new PatternLayout("%c{1}: %m%n"), - // getOutputFile(caseName), false); - root.addAppender(appender); - root.setLevel(Level.DEBUG); - } - - // basic test of plugin in standalone mode - public void test1() throws Exception { - - String testName = "test1"; - Logger logger = Logger.getLogger(testName); - - setupAppender(testName); - - PluginTester plugin1 = new PluginTester1("plugin1", 1); - PluginTester plugin2 = new PluginTester1("plugin1", 2); - PluginTester plugin3 = new PluginTester2("plugin1", 3); - PluginTester plugin4 = new PluginTester2("plugin2", 4); - PluginTester retPlugin; - - repositoryMap.clear(); - repositoryMap.put(LogManager.getLoggerRepository(), - "default repository"); - - // test basic starting/stopping - logger.info("test 1.1 - basic starting/stopping"); - logger.info("starting " + plugin1.getIdentifier()); - pluginRegistry.addPlugin(plugin1); - logger.info("stopping " + plugin1.getIdentifier() + - " using plugin object"); - pluginRegistry.stopPlugin(plugin1.getName()); - - // test restarting and starting when already started - logger.info("test 1.2 - restarting and starting when already started"); - logger.info("restarting " + plugin1.getIdentifier()); - pluginRegistry.addPlugin(plugin1); - logger.info("restarting " + plugin1.getIdentifier() + " again"); - pluginRegistry.addPlugin(plugin1); - - // test stopping and stopping when already stopped - logger.info("test 1.3- stopping and stopping when already stopped"); - logger.info("stopping " + plugin1.getIdentifier()); - pluginRegistry.stopPlugin(plugin1.getName()); - logger.info("stopping " + plugin1.getIdentifier() + " again"); - pluginRegistry.stopPlugin(plugin1.getName()); - - logger.info("test 1.4 - restarting then stopping by plugin name"); - logger.info("starting " + plugin1.getIdentifier()); - pluginRegistry.addPlugin(plugin1); - logger.info("stopping " + plugin1.getIdentifier() + - " using plugin name"); - pluginRegistry.stopPlugin(plugin1.getName()); - -// // test starting of an "equal" plugin -// logger.info("test 1.5 - starting of an \"equal\" plugin"); -// logger.info("starting " + plugin1.getIdentifier()); -// retPlugin = (PluginTester) pluginRegistry.startPlugin(plugin1); -// logger.info("returned plugin is " + retPlugin.getIdentifier()); -// logger.info("starting " + plugin2.getIdentifier()); -// retPlugin = (PluginTester) pluginRegistry.startPlugin(plugin2); -// logger.info("returned plugin is " + retPlugin.getIdentifier()); -// logger.info("stopping " + retPlugin.getIdentifier()); -// pluginRegistry.stopPlugin(retPlugin.getName()); -// -// // test starting an "equal" plugin after original stopped -// logger.info( -// "test 1.6 - starting an \"equal\" plugin after original stopped"); -// logger.info("starting " + plugin2.getIdentifier()); -// retPlugin = (PluginTester) pluginRegistry.startPlugin(plugin2); -// logger.info("returned plugin is " + retPlugin.getIdentifier()); -// logger.info("stopping " + retPlugin.getIdentifier()); -// pluginRegistry.stopPlugin(retPlugin.getName()); -// -// // test starting of an "unequal" plugin with same name -// logger.info( -// "test 1.7 - starting of an \"unequal\" plugin with same name"); -// logger.info("starting " + plugin1.getIdentifier()); -// retPlugin = (PluginTester) pluginRegistry.startPlugin(plugin1); -// logger.info("returned plugin is " + retPlugin.getIdentifier()); -// logger.info("starting " + plugin3.getIdentifier()); -// retPlugin = (PluginTester) pluginRegistry.startPlugin(plugin3); -// logger.info("returned plugin is " + retPlugin.getIdentifier()); -// logger.info("stopping " + retPlugin.getIdentifier()); -// pluginRegistry.stopPlugin(retPlugin.getName()); -// -// // test starting of multiple plugins and stopAll -// logger.info("test 1.8 - starting of multiple plugins and stopAll"); -// logger.info("starting " + plugin1.getIdentifier()); -// retPlugin = (PluginTester) pluginRegistry.startPlugin(plugin1); -// logger.info("returned plugin is " + retPlugin.getIdentifier()); -// logger.info("starting " + plugin4.getIdentifier()); -// retPlugin = (PluginTester) pluginRegistry.startPlugin(plugin4); -// logger.info("returned plugin is " + retPlugin.getIdentifier()); -// verbosePluginOutput = false; -// logger.info("stopping all plugins"); -// pluginRegistry.stopAllPlugins(); -// verbosePluginOutput = true; -// logger.info(plugin1.getIdentifier() + " is " + -// (plugin1.isActive() ? "active" : "inactive")); -// logger.info(plugin4.getIdentifier() + " is " + -// (plugin4.isActive() ? "active" : "inactive")); -// logger.info("stopping all plugins again"); -// pluginRegistry.stopAllPlugins(); -// -// // test starting of multiple plugins and stopAll -// logger.info( -// "test 1.9 - starting of multiple plugins, stopping, and stopAll"); -// logger.info("starting " + plugin1.getIdentifier()); -// retPlugin = (PluginTester) pluginRegistry.startPlugin(plugin1); -// logger.info("returned plugin is " + retPlugin.getIdentifier()); -// logger.info("starting " + plugin4.getIdentifier()); -// retPlugin = (PluginTester) pluginRegistry.startPlugin(plugin4); -// logger.info("returned plugin is " + retPlugin.getIdentifier()); - logger.info("stopping " + plugin1.getIdentifier() + - " using plugin object"); - pluginRegistry.stopPlugin(plugin1.getName()); - verbosePluginOutput = false; - logger.info("stopping all plugins"); - pluginRegistry.stopAllPlugins(); - verbosePluginOutput = true; - logger.info(plugin1.getIdentifier() + " is " + - (plugin1.isActive() ? "active" : "inactive")); - logger.info(plugin4.getIdentifier() + " is " + - (plugin4.isActive() ? "active" : "inactive")); - logger.info("stopping all plugins again"); - pluginRegistry.stopAllPlugins(); - - assertTrue(Compare.compare(getOutputFile(testName), - getWitnessFile(testName))); - } - - // basic test of plugin with repositories - public void test2() throws Exception { -// -// String testName = "test2"; -// Logger logger = Logger.getLogger(testName); -// -// setupAppender(testName); -// -// PluginTester plugin1 = new PluginTester1("plugin1", 1); -// PluginTester plugin2 = new PluginTester1("plugin2", 2); -// PluginTester retPlugin; -// LoggerRepository repo1 = new Hierarchy(new RootLogger(Level.DEBUG)); -// LoggerRepository repo2 = new Hierarchy(new RootLogger(Level.DEBUG)); -// -// PluginRegistry pr1 = repo1.getPluginRegistry(); -// PluginRegistry pr2 = repo2.getPluginRegistry(); -// -// repositoryMap.clear(); -// repositoryMap.put(repo1, "repository1"); -// repositoryMap.put(repo2, "repository2"); -// -// logger.info("test 2.1 - starting plugins in multiple repositories"); -// logger.info("starting " + plugin1.getIdentifier() + " in " + -// repositoryMap.get(repo1)); -// retPlugin = (PluginTester) pr1.startPlugin(plugin1); -// logger.info( -// "returned plugin is " + retPlugin.getIdentifier() + " in " + -// repositoryMap.get(retPlugin.getLoggerRepository())); -// logger.info("starting " + plugin2.getIdentifier() + " in " + -// repositoryMap.get(repo2)); -// retPlugin = (PluginTester) pr2.startPlugin(plugin2); -// logger.info( -// "returned plugin is " + retPlugin.getIdentifier() + " in " + -// repositoryMap.get(retPlugin.getLoggerRepository())); -// -// logger.info("test 2.2 - stopping plugins in multiple repositories"); -// logger.info("stopping " + plugin1.getIdentifier() + " in " + -// repositoryMap.get(plugin1.getLoggerRepository())); -// retPlugin = (PluginTester) pr1.stopPlugin(plugin1.getName()); -// logger.info( -// "returned plugin is " + retPlugin.getIdentifier() + " in " + -// repositoryMap.get(retPlugin.getLoggerRepository())); -// logger.info("stopping " + plugin2.getIdentifier() + " in " + -// repositoryMap.get(plugin2.getLoggerRepository())); -// retPlugin = (PluginTester) pr2.stopPlugin(plugin2.getName()); -// logger.info( -// "returned plugin is " + retPlugin.getIdentifier() + " in " + -// repositoryMap.get(retPlugin.getLoggerRepository())); -// -// logger.info("test 2.3 - restarting plugins in different repositories"); -// logger.info("starting " + plugin1.getIdentifier() + " in " + -// repositoryMap.get(repo2)); -// retPlugin = (PluginTester) pr2.startPlugin(plugin1); -// logger.info( -// "returned plugin is " + retPlugin.getIdentifier() + " in " + -// repositoryMap.get(retPlugin.getLoggerRepository())); -// logger.info("starting " + plugin2.getIdentifier() + " in " + -// repositoryMap.get(repo1)); -// retPlugin = (PluginTester) pr1.startPlugin(plugin2); -// logger.info( -// "returned plugin is " + retPlugin.getIdentifier() + " in " + -// repositoryMap.get(retPlugin.getLoggerRepository())); -// -// logger.info("test 2.4 - stopping plugins using stopAll"); -// logger.info("stopping all plugins in " + repositoryMap.get(repo1)); -// pr1.stopAllPlugins(); -// logger.info("stopping all plugins in " + repositoryMap.get(repo2)); -// pr2.stopAllPlugins(); -// -// logger.info( -// "test 2.5 - starting a plugin already active in another repository"); -// logger.info("starting " + plugin1.getIdentifier() + " in " + -// repositoryMap.get(repo1)); -// retPlugin = (PluginTester) pr1.startPlugin(plugin1); -// logger.info( -// "returned plugin is " + retPlugin.getIdentifier() + " in " + -// repositoryMap.get(retPlugin.getLoggerRepository())); -// logger.info("starting " + plugin2.getIdentifier() + " in " + -// repositoryMap.get(repo2)); -// retPlugin = (PluginTester) pr2.startPlugin(plugin2); -// logger.info( -// "returned plugin is " + retPlugin.getIdentifier() + " in " + -// repositoryMap.get(retPlugin.getLoggerRepository())); -// logger.info("restarting " + plugin1.getIdentifier() + " in " + -// repositoryMap.get(repo2)); -// retPlugin = (PluginTester) pr2.startPlugin(plugin1); -// logger.info( -// "returned plugin is " + retPlugin.getIdentifier() + " in " + -// repositoryMap.get(retPlugin.getLoggerRepository())); -// logger.info("restarting " + plugin2.getIdentifier() + " in " + -// repositoryMap.get(repo1)); -// retPlugin = (PluginTester) pr1.startPlugin(plugin2); -// logger.info( -// "returned plugin is " + retPlugin.getIdentifier() + " in " + -// repositoryMap.get(retPlugin.getLoggerRepository())); -// -// logger.info("test 2.6 - handle repository reset"); -// logger.info("resetting " + repositoryMap.get(repo1)); -// repo1.resetConfiguration(); -// logger.info("resetting " + repositoryMap.get(repo2)); -// repo2.resetConfiguration(); -// -// logger.info("test 2.7 - handle repository shutdown"); -// logger.info("starting " + plugin1.getIdentifier() + " in " + -// repositoryMap.get(repo1)); -// retPlugin = (PluginTester) pr1.startPlugin(plugin1); -// logger.info( -// "returned plugin is " + retPlugin.getIdentifier() + " in " + -// repositoryMap.get(retPlugin.getLoggerRepository())); -// logger.info("starting " + plugin2.getIdentifier() + " in " + -// repositoryMap.get(repo2)); -// retPlugin = (PluginTester) pr2.startPlugin(plugin2); -// logger.info( -// "returned plugin is " + retPlugin.getIdentifier() + " in " + -// repositoryMap.get(retPlugin.getLoggerRepository())); -// logger.info("shutting down " + repositoryMap.get(repo1)); -// repo1.shutdown(); -// logger.info("shutting down " + repositoryMap.get(repo2)); -// repo2.shutdown(); -// -// assertTrue(Compare.compare(getOutputFile(testName), -// getWitnessFile(testName))); - } - - public void testPluginListeners() { - - Plugin p = new PluginTester1("MyNewPlugin", 1); - PluginListenerLatch l = new PluginListenerLatch(); - pluginRegistry.stopAllPlugins(); - pluginRegistry.addPluginListener(l); - pluginRegistry.addPlugin(p); - - PluginEvent e = l.LastEvent; - - assertTrue("PluginListener should have been notified of start", - l.StartLatch); - assertTrue("PluginListener stop latch should not be activated", - !l.StopLatch); - assertTrue("PluginListener should be given reference to Plugin", - e.getPlugin() == p); - - l.reset(); - pluginRegistry.stopAllPlugins(); - assertTrue("PluginListener should have been notified of stop", - l.StopLatch); - assertTrue("PluginListener should not have been notified of start", - !l.StartLatch); - assertTrue("PluginListener should be given reference to Plugin", - l.LastEvent.getPlugin() == p); - assertTrue( - "PluginListener should have received a distinct event object", - l.LastEvent != e); - } - - public void testPropertyChangeListeners() { - - Plugin plugin = new PluginTester1("PluginTest1", 1); - - final PropertyChangeListenerLatch l = new PropertyChangeListenerLatch(); - plugin.addPropertyChangeListener(l); - - /** - * Test the basic properties and ensure they get latched by notification - */ - plugin.setName("NewName"); - assertTrue("PropertyChange latch should have been detected", - l.isLatched()); - assertTrue("Old value unexpected: '" + l.getLastEvent().getOldValue() + - "'", l.getLastEvent().getOldValue().equals("PluginTest1")); - assertTrue("New value unexpected: '" + l.getLastEvent().getNewValue() + - "'", l.getLastEvent().getNewValue().equals("NewName")); - - l.reset(); - - plugin.removePropertyChangeListener(l); - plugin.setName("SecondNewName"); - - assertTrue("Should not have been notified/latched", !l.isLatched()); - - l.reset(); - - /** - * Test when only listening for specific property - */ - plugin.addPropertyChangeListener("name", l); - - plugin.setName("NewName2"); - assertTrue("PropertyChange latch should have been detected", - l.isLatched()); - assertTrue("Old value unexpected: '" + l.getLastEvent().getOldValue() + - "'", l.getLastEvent().getOldValue().equals("SecondNewName")); - assertTrue("New value unexpected: '" + l.getLastEvent().getNewValue() + - "'", l.getLastEvent().getNewValue().equals("NewName2")); - - plugin.removePropertyChangeListener("name", l); - - l.reset(); - - /** - * setup some assertions before continuing testing to make sure the test code isn't broken - */ - assertTrue("Plugin should not be active just yet", !plugin.isActive()); - assertTrue("Latch should not be latched", !l.isLatched()); - - plugin.addPropertyChangeListener("active", l); - - pluginRegistry.addPlugin(plugin); -/* - assertTrue( - "Should have been notified of activation when pluginRegistry.start(plugin)", - l.isLatched()); - assertTrue("Active old value should have been false", - l.getLastEvent().getOldValue().equals(Boolean.FALSE)); - assertTrue("Active New value should have been true", - l.getLastEvent().getNewValue().equals(Boolean.TRUE)); - - pluginRegistry.stopAllPlugins(); - l.reset(); - assertTrue("Latch should have been reset", !l.isLatched()); -*/ - - /** - * start afresh - */ -/* - plugin = new PluginTester1("LoggerRepositoryProperty", 2); - - LoggerRepository oldValue = plugin.getLoggerRepository(); - plugin.addPropertyChangeListener("loggerRepository", l); - - LoggerRepository rep = new Hierarchy(new RootLogger(Level.DEBUG)); - plugin.setLoggerRepository(rep); - - assertTrue("Should be notified of LoggerRepository property change", - l.isLatched()); - assertTrue("LoggerRepository Old value mismatch", - l.getLastEvent().getOldValue() == oldValue); - assertTrue("LoggerRepository New vale mismatch", - l.getLastEvent().getNewValue() == rep); -*/ - } - - private static class PluginListenerLatch implements PluginListener { - - private boolean StartLatch; - private boolean StopLatch; - private PluginEvent LastEvent; - - /* (non-Javadoc) - * @see org.apache.log4j.plugins.PluginListener#pluginStarted(org.apache.log4j.plugins.PluginEvent) - */ - public void pluginStarted(PluginEvent e) { - StartLatch = true; - LastEvent = e; - } - - /* (non-Javadoc) - * @see org.apache.log4j.plugins.PluginListener#pluginStopped(org.apache.log4j.plugins.PluginEvent) - */ - public void pluginStopped(PluginEvent e) { - StopLatch = true; - LastEvent = e; - } - - void reset() { - StartLatch = false; - StopLatch = false; - LastEvent = null; - } - } - - private static class PropertyChangeListenerLatch - implements PropertyChangeListener { - - boolean latch = false; - PropertyChangeEvent lastEvent = null; - - /* (non-Javadoc) - * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent) - */ - public void propertyChange(PropertyChangeEvent evt) { - latch = true; - lastEvent = evt; - } - - boolean isLatched() { - - return latch; - } - - void reset() { - latch = false; - lastEvent = null; - } - - PropertyChangeEvent getLastEvent() { - - return lastEvent; - } - } - - /** - Class to test the Plugin and PluginRegistry functionality. */ - private static class PluginTester extends PluginSkeleton { - - protected Logger logger; - private boolean active = false; - public int id; - - public synchronized boolean isActive() { - logger.debug(this.getIdentifier() + " is " + - (active ? "active" : "inactive")); - - return active; - } - - private synchronized boolean setActive(boolean _active) { - - boolean oldValue = active; - - if (active != _active) { - active = _active; - firePropertyChange("active", oldValue, active); - - return true; - } else { - - return false; - } - } - - public String getIdentifier() { - - if (verbosePluginOutput) { - - return this.getName() + "-id" + id; - } else { - - return "plugin in " + - repositoryMap.get(this.getLoggerRepository()); - } - } - - public void activateOptions() { - - if (setActive(true)) { - logger.debug(this.getIdentifier() + " activated"); - } else { - logger.debug(this.getIdentifier() + " already activated"); - } - } - - public void shutdown() { - - if (setActive(false)) { - logger.debug(this.getIdentifier() + " shutdown"); - } else { - logger.debug(this.getIdentifier() + " already shutdown"); - } - } - - /* (non-Javadoc) - * @see org.apache.log4j.plugins.Plugin#isEquivalent(org.apache.log4j.plugins.Plugin) - */ - public boolean isEquivalent(Plugin testPlugin) { - - boolean equiv = super.isEquivalent(testPlugin); - - if (equiv) { - logger.debug("plugin equal"); - } else if (!(testPlugin.getClass() == this.getClass())) { - logger.debug( - "plugin not equal, different class: " + - this.getClass().getName() + " != " + - testPlugin.getClass().getName()); - - } else if (!this.getName().equals(testPlugin.getName())) { - logger.debug( - "plugin not equal, different name: " + this.getName() + - " != " + testPlugin.getName()); - - } else if (!this.getLoggerRepository().equals( - testPlugin.getLoggerRepository())) { - logger.debug( - "plugin not equal, different repository: " + - repositoryMap.get(this.getLoggerRepository()) + " != " + - repositoryMap.get(testPlugin.getLoggerRepository())); - } - - return equiv; - } - } - - /** - Class to test the Plugin and PluginRegistry functionality. */ - private static class PluginTester1 extends PluginTester { - public PluginTester1(String _name, int _id) { - logger = Logger.getLogger(this.getClass()); - setName(_name); - id = _id; - } - } - - /** - Class to test the Plugin and PluginRegistry functionality. */ - private static class PluginTester2 extends PluginTester { - public PluginTester2(String _name, int _id) { - logger = Logger.getLogger(this.getClass()); - setName(_name); - id = _id; - } - } -} diff --git a/tests/src/java/org/apache/log4j/rewrite/RewriteAppenderTest.java b/tests/src/java/org/apache/log4j/rewrite/RewriteAppenderTest.java new file mode 100644 index 0000000000..4328dc9bf7 --- /dev/null +++ b/tests/src/java/org/apache/log4j/rewrite/RewriteAppenderTest.java @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.rewrite; + +import junit.framework.*; +import org.apache.log4j.*; +import org.apache.log4j.util.Compare; +import org.apache.log4j.xml.*; + +import java.io.InputStream; +import java.util.Map; +import java.util.TreeMap; +import java.util.Hashtable; +import javax.xml.parsers.*; +import org.w3c.dom.*; + +public class RewriteAppenderTest extends TestCase { + public RewriteAppenderTest(final String name) { + super(name); + } + + public void setUp() { + LogManager.getLoggerRepository().resetConfiguration(); + Hashtable context = MDC.getContext(); + if (context != null) { + context.clear(); + } + } + + public void tearDown() { + LogManager.getLoggerRepository().shutdown(); + } + + public void configure(final String resourceName) throws Exception { + InputStream is = RewriteAppenderTest.class.getResourceAsStream(resourceName); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(false); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(is); + DOMConfigurator.configure(doc.getDocumentElement()); + } + + + public void testMapPolicy() throws Exception { + configure("map.xml"); + Logger logger = Logger.getLogger(RewriteAppenderTest.class); + logger.info("Message 0"); + MDC.put("p1", "Hola"); + + Map msg = new TreeMap(); + msg.put("p1", "Hello"); + msg.put("p2", "World"); + msg.put("x1", "Mundo"); + logger.info(msg); + msg.put("message", "Message 1"); + logger.info(msg); + assertTrue(Compare.compare(RewriteAppenderTest.class, "temp", "map.log")); + } + + private static class BaseBean { + private final Object p2; + private final Object x1; + + public BaseBean(final Object p2, + final Object x1) { + this.p2 = p2; + this.x1 = x1; + } + + public Object getP2() { + return p2; + } + + public Object getX1() { + return x1; + } + + public String toString() { + return "I am bean."; + } + } + + private static class MessageBean extends BaseBean { + private final Object msg; + + public MessageBean(final Object msg, + final Object p2, + final Object x1) { + super(p2, x1); + this.msg = msg; + } + + public Object getMessage() { + return msg; + } + } + + public void testReflectionPolicy() throws Exception { + configure("reflection.xml"); + Logger logger = Logger.getLogger(RewriteAppenderTest.class); + logger.info("Message 0"); + logger.info(new BaseBean("Hello", "World" )); + MDC.put("p1", "Hola"); + MDC.put("p2", "p2"); + logger.info(new MessageBean("Welcome to The Hub", "Hello", "World" )); + assertTrue(Compare.compare(RewriteAppenderTest.class, "temp", "reflection.log")); + } + + public void testPropertyPolicy() throws Exception { + configure("property.xml"); + Logger logger = Logger.getLogger(RewriteAppenderTest.class); + logger.info("Message 0"); + MDC.put("p1", "Hola"); + logger.info("Message 1"); + assertTrue(Compare.compare(RewriteAppenderTest.class, "temp", "property.log")); + } +} diff --git a/tests/src/java/org/apache/log4j/rolling/FileOpener.java b/tests/src/java/org/apache/log4j/rolling/FileOpener.java deleted file mode 100644 index aad8b9f846..0000000000 --- a/tests/src/java/org/apache/log4j/rolling/FileOpener.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling; - -import java.io.FileInputStream; -import java.io.InputStream; - - -/** - * Keep the file "output/test.log open for 10 seconds so that we can test - * RollingFileAppender's ability to roll file open by another process. - * @author Ceki Gülcü - */ -public class FileOpener { - public static void main(String[] args) throws Exception { - InputStream is = new FileInputStream("output/test.log"); - is.read(); - Thread.sleep(10000); - is.close(); - System.out.println("Exiting FileOpener"); - } -} diff --git a/tests/src/java/org/apache/log4j/rolling/FilterBasedRollingTest.java b/tests/src/java/org/apache/log4j/rolling/FilterBasedRollingTest.java deleted file mode 100644 index 88f02246b3..0000000000 --- a/tests/src/java/org/apache/log4j/rolling/FilterBasedRollingTest.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling; - -import junit.framework.TestCase; -import org.apache.log4j.Appender; -import org.apache.log4j.ConsoleAppender; -import org.apache.log4j.Level; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.PatternLayout; -import org.apache.log4j.filter.LevelRangeFilter; -import org.apache.log4j.joran.JoranConfigurator; -import org.apache.log4j.util.Compare; - - -/** - * - * Tests of rolling file appender with a filter based triggering policy. - * - * @author Curt Arnold - * @since 1.3 - * - */ -public class FilterBasedRollingTest extends TestCase { - public FilterBasedRollingTest(String name) { - super(name); - } - - public void setUp() { - Appender ca = new ConsoleAppender(new PatternLayout("%d %level %c -%m%n")); - ca.setName("CONSOLE"); - Logger.getRootLogger().addAppender(ca); - } - - public void tearDown() { - LogManager.getLoggerRepository().resetConfiguration(); - } - - /** - * Test basic rolling functionality using configuration file. - */ - public void test1() throws Exception { - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure( - "./input/rolling/filter1.xml", LogManager.getLoggerRepository()); - jc.dumpErrors(); - - common("output/filterBased-test1"); - } - - /** - * Test basic rolling functionality using explicit configuration. - * Test fails when run immediately after test1. - */ - public void test2() throws Exception { - PatternLayout layout = new PatternLayout("%m\n"); - RollingFileAppender rfa = new RollingFileAppender(); - rfa.setName("ROLLING"); - rfa.setLayout(layout); - - FixedWindowRollingPolicy swrp = new FixedWindowRollingPolicy(); - FilterBasedTriggeringPolicy fbtp = new FilterBasedTriggeringPolicy(); - - LevelRangeFilter rf = new LevelRangeFilter(); - rf.setLevelMin(Level.INFO); - fbtp.addFilter(rf); - fbtp.activateOptions(); - - swrp.setMinIndex(0); - rfa.setFile("output/filterBased-test2.log"); - rfa.setAppend(false); - - swrp.setFileNamePattern("output/filterBased-test2.%i"); - swrp.activateOptions(); - - rfa.setRollingPolicy(swrp); - rfa.setTriggeringPolicy(fbtp); - rfa.activateOptions(); - Logger.getRootLogger().addAppender(rfa); - Logger.getRootLogger().setLevel(Level.DEBUG); - - common("output/filterBased-test2"); - } - - /** - * Common aspects of test1 and test2 - */ - private void common(String baseName) throws Exception { - Logger logger = Logger.getLogger(FilterBasedRollingTest.class); - - // Write exactly 10 bytes with each log - for (int i = 0; i < 25; i++) { - Thread.sleep(100); - - if (i < 10) { - logger.debug("Hello---" + i); - } else if (i < 100) { - if ((i % 10) == 0) { - // on the 10th and 20th request, raise the severity - logger.warn("Hello--" + i); - } else { - logger.debug("Hello--" + i); - } - } - } - - // - // test was constructed to mimic SizeBasedRollingTest.test2 - // - assertTrue( - Compare.compare(baseName + ".log", "witness/rolling/sbr-test2.log")); - assertTrue( - Compare.compare(baseName + ".0", "witness/rolling/sbr-test2.0")); - assertTrue( - Compare.compare(baseName + ".1", "witness/rolling/sbr-test2.1")); - } -} diff --git a/tests/src/java/org/apache/log4j/rolling/RenamingTest.java b/tests/src/java/org/apache/log4j/rolling/RenamingTest.java deleted file mode 100644 index a6fef69e44..0000000000 --- a/tests/src/java/org/apache/log4j/rolling/RenamingTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling; - -import java.text.SimpleDateFormat; -import java.util.Calendar; - -import junit.framework.TestCase; - -import org.apache.log4j.ConsoleAppender; -import org.apache.log4j.Logger; -import org.apache.log4j.PatternLayout; -import org.apache.log4j.util.Compare; -import java.io.File; - - -/** - * - * This test case aims to unit test/reproduce problems encountered while - * renaming the log file under windows. - * - * @author Ceki - * - */ -public class RenamingTest extends TestCase { - Logger logger = Logger.getLogger(RenamingTest.class); - - Logger root; - PatternLayout layout; - - public RenamingTest(String arg0) { - super(arg0); - } - - protected void setUp() throws Exception { - super.setUp(); - root = Logger.getRootLogger(); - layout = new PatternLayout("%c{1} - %m%n"); - root.addAppender(new ConsoleAppender(new PatternLayout())); - - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - - public void testRename() throws Exception { - - RollingFileAppender rfa = new RollingFileAppender(); - rfa.setLayout(layout); - rfa.setAppend(false); - - // rollover by the second - String datePattern = "yyyy-MM-dd_HH_mm_ss"; - SimpleDateFormat sdf = new SimpleDateFormat(datePattern); - - TimeBasedRollingPolicy tbrp = new TimeBasedRollingPolicy(); - tbrp.setFileNamePattern("output/test-%d{" + datePattern + "}"); - rfa.setFile("output/test.log"); - tbrp.activateOptions(); - rfa.setRollingPolicy(tbrp); - rfa.activateOptions(); - - Calendar cal = Calendar.getInstance(); - - root.addAppender(rfa); - logger.debug("Hello " + 0); - Thread.sleep(5000); - logger.debug("Hello " + 1); - - String rolledFile = "output/test-" + sdf.format(cal.getTime()); - - // - // if the rolled file exists - // either the test wasn't run from the Ant script - // which opens test.log in another process or - // the test is running on a platform that allows open files to be renamed - if (new File(rolledFile).exists()) { - assertTrue(Compare.compare(rolledFile, "witness/rolling/renaming.0")); - assertTrue(Compare.compare("output/test.log", "witness/rolling/renaming.1")); - } else { - // - // otherwise the rollover should have been blocked - // - assertTrue(Compare.compare("output/test.log", "witness/rolling/renaming.2")); - } - } -} diff --git a/tests/src/java/org/apache/log4j/rolling/SizeBasedRollingTest.java b/tests/src/java/org/apache/log4j/rolling/SizeBasedRollingTest.java deleted file mode 100644 index 5ba5a86e00..0000000000 --- a/tests/src/java/org/apache/log4j/rolling/SizeBasedRollingTest.java +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling; - -import java.io.File; -import java.io.FileOutputStream; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.apache.log4j.Appender; -import org.apache.log4j.ConsoleAppender; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.PatternLayout; -import org.apache.log4j.util.Compare; - - -/** - * - * Do not forget to call activateOptions when configuring programatically. - * - * @author Ceki Gülcü - * - */ -public class SizeBasedRollingTest extends TestCase { - Logger logger = Logger.getLogger(SizeBasedRollingTest.class); - Logger root = Logger.getRootLogger(); - - public SizeBasedRollingTest(String name) { - super(name); - } - - public void setUp() { - Appender ca = new ConsoleAppender(new PatternLayout("%d %level %c -%m%n")); - ca.setName("CONSOLE"); - root.addAppender(ca); - } - - public void tearDown() { - LogManager.shutdown(); - } - - /** - * Tests that the lack of an explicit active file will use the - * low index as the active file. - * - */ - public void test1() throws Exception { - PatternLayout layout = new PatternLayout("%m\n"); - RollingFileAppender rfa = new RollingFileAppender(); - rfa.setName("ROLLING"); - rfa.setAppend(false); - rfa.setLayout(layout); - - FixedWindowRollingPolicy swrp = new FixedWindowRollingPolicy(); - SizeBasedTriggeringPolicy sbtp = new SizeBasedTriggeringPolicy(); - - sbtp.setMaxFileSize(100); - swrp.setMinIndex(0); - - swrp.setFileNamePattern("output/sizeBased-test1.%i"); - swrp.activateOptions(); - - rfa.setRollingPolicy(swrp); - rfa.setTriggeringPolicy(sbtp); - rfa.activateOptions(); - root.addAppender(rfa); - - // Write exactly 10 bytes with each log - for (int i = 0; i < 25; i++) { - if (i < 10) { - logger.debug("Hello---" + i); - } else if (i < 100) { - logger.debug("Hello--" + i); - } - } - - assertTrue(new File("output/sizeBased-test1.0").exists()); - assertTrue(new File("output/sizeBased-test1.1").exists()); - assertTrue(new File("output/sizeBased-test1.2").exists()); - - assertTrue(Compare.compare("output/sizeBased-test1.0", - "witness/rolling/sbr-test2.log")); - assertTrue(Compare.compare("output/sizeBased-test1.1", - "witness/rolling/sbr-test2.0")); - assertTrue(Compare.compare("output/sizeBased-test1.2", - "witness/rolling/sbr-test2.1")); - } - - /** - * Test basic rolling functionality with explicit setting of FileAppender.file. - */ - public void test2() throws Exception { - PatternLayout layout = new PatternLayout("%m\n"); - RollingFileAppender rfa = new RollingFileAppender(); - rfa.setName("ROLLING"); - rfa.setAppend(false); - rfa.setLayout(layout); - rfa.setFile("output/sizeBased-test2.log"); - - FixedWindowRollingPolicy swrp = new FixedWindowRollingPolicy(); - SizeBasedTriggeringPolicy sbtp = new SizeBasedTriggeringPolicy(); - - sbtp.setMaxFileSize(100); - swrp.setMinIndex(0); - - swrp.setFileNamePattern("output/sizeBased-test2.%i"); - swrp.activateOptions(); - - rfa.setRollingPolicy(swrp); - rfa.setTriggeringPolicy(sbtp); - rfa.activateOptions(); - root.addAppender(rfa); - - // Write exactly 10 bytes with each log - for (int i = 0; i < 25; i++) { - if (i < 10) { - logger.debug("Hello---" + i); - } else if (i < 100) { - logger.debug("Hello--" + i); - } - } - - assertTrue(new File("output/sizeBased-test2.log").exists()); - assertTrue(new File("output/sizeBased-test2.0").exists()); - assertTrue(new File("output/sizeBased-test2.1").exists()); - - assertTrue(Compare.compare("output/sizeBased-test2.log", - "witness/rolling/sbr-test2.log")); - assertTrue(Compare.compare("output/sizeBased-test2.0", - "witness/rolling/sbr-test2.0")); - assertTrue(Compare.compare("output/sizeBased-test2.1", - "witness/rolling/sbr-test2.1")); - } - - /** - * Same as testBasic but also with GZ compression. - */ - public void test3() throws Exception { - PatternLayout layout = new PatternLayout("%m\n"); - RollingFileAppender rfa = new RollingFileAppender(); - rfa.setAppend(false); - rfa.setLayout(layout); - - FixedWindowRollingPolicy fwrp = new FixedWindowRollingPolicy(); - SizeBasedTriggeringPolicy sbtp = new SizeBasedTriggeringPolicy(); - - sbtp.setMaxFileSize(100); - fwrp.setMinIndex(0); - rfa.setFile("output/sbr-test3.log"); - fwrp.setFileNamePattern("output/sbr-test3.%i.gz"); - fwrp.activateOptions(); - rfa.setRollingPolicy(fwrp); - rfa.setTriggeringPolicy(sbtp); - rfa.activateOptions(); - root.addAppender(rfa); - - // Write exactly 10 bytes with each log - for (int i = 0; i < 25; i++) { - Thread.sleep(100); - if (i < 10) { - logger.debug("Hello---" + i); - } else if (i < 100) { - logger.debug("Hello--" + i); - } - } - - assertTrue(new File("output/sbr-test3.log").exists()); - assertTrue(new File("output/sbr-test3.0.gz").exists()); - assertTrue(new File("output/sbr-test3.1.gz").exists()); - - assertTrue(Compare.compare("output/sbr-test3.log", "witness/rolling/sbr-test3.log")); - assertTrue(Compare.gzCompare("output/sbr-test3.0.gz", "witness/rolling/sbr-test3.0.gz")); - assertTrue(Compare.gzCompare("output/sbr-test3.1.gz", "witness/rolling/sbr-test3.1.gz")); - } - - /** - * Test basic rolling functionality with bogus path in file name pattern. - */ - public void test4() throws Exception { - PatternLayout layout = new PatternLayout("%m\n"); - RollingFileAppender rfa = new RollingFileAppender(); - rfa.setName("ROLLING"); - rfa.setAppend(false); - rfa.setLayout(layout); - rfa.setFile("output/sizeBased-test4.log"); - - FixedWindowRollingPolicy swrp = new FixedWindowRollingPolicy(); - SizeBasedTriggeringPolicy sbtp = new SizeBasedTriggeringPolicy(); - - sbtp.setMaxFileSize(100); - swrp.setMinIndex(0); - - // - // test4 directory should not exists. Should cause all rollover attempts to fail. - // - swrp.setFileNamePattern("output/test4/sizeBased-test4.%i"); - swrp.activateOptions(); - - rfa.setRollingPolicy(swrp); - rfa.setTriggeringPolicy(sbtp); - rfa.activateOptions(); - root.addAppender(rfa); - - // Write exactly 10 bytes with each log - for (int i = 0; i < 25; i++) { - if (i < 10) { - logger.debug("Hello---" + i); - } else if (i < 100) { - logger.debug("Hello--" + i); - } - } - - assertTrue(new File("output/sizeBased-test4.log").exists()); - - assertTrue(Compare.compare("output/sizeBased-test4.log", - "witness/rolling/sbr-test4.log")); - } - - /** - * Checking handling of rename failures due to other access - * to the indexed files. - */ - public void test5() throws Exception { - PatternLayout layout = new PatternLayout("%m\n"); - RollingFileAppender rfa = new RollingFileAppender(); - rfa.setName("ROLLING"); - rfa.setAppend(false); - rfa.setLayout(layout); - rfa.setFile("output/sizeBased-test5.log"); - - FixedWindowRollingPolicy swrp = new FixedWindowRollingPolicy(); - SizeBasedTriggeringPolicy sbtp = new SizeBasedTriggeringPolicy(); - - sbtp.setMaxFileSize(100); - swrp.setMinIndex(0); - - swrp.setFileNamePattern("output/sizeBased-test5.%i"); - swrp.activateOptions(); - - rfa.setRollingPolicy(swrp); - rfa.setTriggeringPolicy(sbtp); - rfa.activateOptions(); - root.addAppender(rfa); - - // - // put stray file about locked file - FileOutputStream os1 = new FileOutputStream("output/sizeBased-test5.1"); - os1.close(); - - - FileOutputStream os0 = new FileOutputStream("output/sizeBased-test5.0"); - - // Write exactly 10 bytes with each log - for (int i = 0; i < 25; i++) { - if (i < 10) { - logger.debug("Hello---" + i); - } else if (i < 100) { - logger.debug("Hello--" + i); - } - } - - os0.close(); - - if (new File("output/sizeBased-test5.3").exists()) { - // - // looks like platform where open files can be renamed - // - assertTrue(new File("output/sizeBased-test5.log").exists()); - assertTrue(new File("output/sizeBased-test5.0").exists()); - assertTrue(new File("output/sizeBased-test5.1").exists()); - assertTrue(new File("output/sizeBased-test5.2").exists()); - assertTrue(new File("output/sizeBased-test5.3").exists()); - - assertTrue(Compare.compare("output/sizeBased-test5.log", - "witness/rolling/sbr-test2.log")); - assertTrue(Compare.compare("output/sizeBased-test5.0", - "witness/rolling/sbr-test2.0")); - assertTrue(Compare.compare("output/sizeBased-test5.1", - "witness/rolling/sbr-test2.1")); - - } else { - // - // rollover attempts should all fail - // so initial log file should have all log content - // open file should be unaffected - // stray file should have only been moved one slot. - assertTrue(new File("output/sizeBased-test5.log").exists()); - assertTrue(new File("output/sizeBased-test5.0").exists()); - assertTrue(new File("output/sizeBased-test5.2").exists()); - - assertTrue(Compare.compare("output/sizeBased-test5.log", - "witness/rolling/sbr-test4.log")); - } - } - - - /** - * Test basic rolling functionality with explicit setting of - * obsolete FixedWindowRollingPolicy.activeFileName. - * @deprecated Tests deprecated method - */ - public void test6() throws Exception { - PatternLayout layout = new PatternLayout("%m\n"); - RollingFileAppender rfa = new RollingFileAppender(); - rfa.setName("ROLLING"); - rfa.setAppend(false); - rfa.setLayout(layout); - - FixedWindowRollingPolicy swrp = new FixedWindowRollingPolicy(); - SizeBasedTriggeringPolicy sbtp = new SizeBasedTriggeringPolicy(); - - sbtp.setMaxFileSize(100); - swrp.setMinIndex(0); - swrp.setActiveFileName("output/sizeBased-test6.log"); - - swrp.setFileNamePattern("output/sizeBased-test6.%i"); - swrp.activateOptions(); - - rfa.setRollingPolicy(swrp); - rfa.setTriggeringPolicy(sbtp); - rfa.activateOptions(); - root.addAppender(rfa); - - // Write exactly 10 bytes with each log - for (int i = 0; i < 25; i++) { - if (i < 10) { - logger.debug("Hello---" + i); - } else if (i < 100) { - logger.debug("Hello--" + i); - } - } - - assertTrue(new File("output/sizeBased-test6.log").exists()); - assertTrue(new File("output/sizeBased-test6.0").exists()); - assertTrue(new File("output/sizeBased-test6.1").exists()); - - assertTrue(Compare.compare("output/sizeBased-test6.log", - "witness/rolling/sbr-test2.log")); - assertTrue(Compare.compare("output/sizeBased-test6.0", - "witness/rolling/sbr-test2.0")); - assertTrue(Compare.compare("output/sizeBased-test6.1", - "witness/rolling/sbr-test2.1")); - } - - -} diff --git a/tests/src/java/org/apache/log4j/rolling/TimeBasedRollingTest.java b/tests/src/java/org/apache/log4j/rolling/TimeBasedRollingTest.java deleted file mode 100644 index 7144c572cd..0000000000 --- a/tests/src/java/org/apache/log4j/rolling/TimeBasedRollingTest.java +++ /dev/null @@ -1,487 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.rolling; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.apache.log4j.ConsoleAppender; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.PatternLayout; -import org.apache.log4j.joran.JoranConfigurator; -import org.apache.log4j.util.Compare; - -import java.text.SimpleDateFormat; - -import java.util.Calendar; -import java.util.Date; - - -/** - * A rather exhaustive set of tests. Tests include leaving the ActiveFileName - * argument blank, or setting it, with and without compression, and tests - * with or without stopping/restarting the RollingFileAppender. - * - * The regression tests log a few times using a RollingFileAppender. Then, - * they predict the names of the files which sould be generated and compare - * them with witness files. - * - *
    -         Compression    ActiveFileName  Stop/Restart 
    - Test1      NO              BLANK          NO
    - Test2      NO              BLANK          YES
    - Test3      YES             BLANK          NO
    - Test4      NO                SET          YES 
    - Test5      NO                SET          NO
    - Test6      YES               SET          NO
    - * 
    - * @author Ceki Gülcü - */ -public class TimeBasedRollingTest extends TestCase { - Logger logger = Logger.getLogger(TimeBasedRollingTest.class); - - public TimeBasedRollingTest(String name) { - super(name); - } - - public void setUp() { - Logger root = Logger.getRootLogger(); - root.addAppender( - new ConsoleAppender(new PatternLayout("%d{ABSOLUTE} [%t] %level %c{2}#%M:%L - %m%n"))); - } - - public void tearDown() { - LogManager.shutdown(); - } - - /** - * Test rolling without compression, activeFileName left blank, no stop/start - */ - public void test1() throws Exception { - PatternLayout layout = new PatternLayout("%c{1} - %m%n"); - RollingFileAppender rfa = new RollingFileAppender(); - rfa.setLayout(layout); - - String datePattern = "yyyy-MM-dd_HH_mm_ss"; - - TimeBasedRollingPolicy tbrp = new TimeBasedRollingPolicy(); - tbrp.setFileNamePattern("output/test1-%d{" + datePattern + "}"); - tbrp.activateOptions(); - rfa.setRollingPolicy(tbrp); - rfa.activateOptions(); - logger.addAppender(rfa); - - SimpleDateFormat sdf = new SimpleDateFormat(datePattern); - String[] filenames = new String[4]; - - Calendar cal = Calendar.getInstance(); - - for (int i = 0; i < 4; i++) { - filenames[i] = "output/test1-" + sdf.format(cal.getTime()); - cal.add(Calendar.SECOND, 1); - } - - System.out.println("Waiting until next second and 100 millis."); - delayUntilNextSecond(100); - System.out.println("Done waiting."); - - for (int i = 0; i < 5; i++) { - logger.debug("Hello---" + i); - Thread.sleep(500); - } - - for (int i = 0; i < 4; i++) { - //System.out.println(i + " expected filename [" + filenames[i] + "]."); - } - - for (int i = 0; i < 4; i++) { - assertTrue(Compare.compare(filenames[i], "witness/rolling/tbr-test1." + i)); - } - } - - /** - * No compression, with stop/restart, activeFileName left blank - */ - public void test2() throws Exception { - String datePattern = "yyyy-MM-dd_HH_mm_ss"; - - PatternLayout layout1 = new PatternLayout("%c{1} - %m%n"); - RollingFileAppender rfa1 = new RollingFileAppender(); - rfa1.setLayout(layout1); - - TimeBasedRollingPolicy tbrp1 = new TimeBasedRollingPolicy(); - tbrp1.setFileNamePattern("output/test2-%d{" + datePattern + "}"); - tbrp1.activateOptions(); - rfa1.setRollingPolicy(tbrp1); - rfa1.activateOptions(); - logger.addAppender(rfa1); - - SimpleDateFormat sdf = new SimpleDateFormat(datePattern); - String[] filenames = new String[4]; - - Calendar cal = Calendar.getInstance(); - - for (int i = 0; i < 4; i++) { - filenames[i] = "output/test2-" + sdf.format(cal.getTime()); - cal.add(Calendar.SECOND, 1); - } - - System.out.println("Waiting until next second and 100 millis."); - delayUntilNextSecond(100); - System.out.println("Done waiting."); - - for (int i = 0; i <= 2; i++) { - logger.debug("Hello---" + i); - Thread.sleep(500); - } - - logger.removeAppender(rfa1); - rfa1.close(); - - PatternLayout layout2 = new PatternLayout("%c{1} - %m%n"); - RollingFileAppender rfa2 = new RollingFileAppender(); - rfa2.setLayout(layout2); - - TimeBasedRollingPolicy tbrp2 = new TimeBasedRollingPolicy(); - tbrp2.setFileNamePattern("output/test2-%d{" + datePattern + "}"); - tbrp2.activateOptions(); - rfa2.setRollingPolicy(tbrp2); - rfa2.activateOptions(); - logger.addAppender(rfa2); - - for (int i = 3; i <= 4; i++) { - logger.debug("Hello---" + i); - Thread.sleep(500); - } - - rfa2.close(); - - for (int i = 0; i < 4; i++) { - assertTrue(Compare.compare(filenames[i], "witness/rolling/tbr-test2." + i)); - } - } - - /** - * With compression, activeFileName left blank, no stop/restart - */ - public void test3() throws Exception { - PatternLayout layout = new PatternLayout("%c{1} - %m%n"); - RollingFileAppender rfa = new RollingFileAppender(); - rfa.setLayout(layout); - - String datePattern = "yyyy-MM-dd_HH_mm_ss"; - - TimeBasedRollingPolicy tbrp = new TimeBasedRollingPolicy(); - tbrp.setFileNamePattern("output/test3-%d{" + datePattern + "}.gz"); - tbrp.activateOptions(); - rfa.setRollingPolicy(tbrp); - rfa.activateOptions(); - logger.addAppender(rfa); - - SimpleDateFormat sdf = new SimpleDateFormat(datePattern); - String[] filenames = new String[4]; - - Calendar cal = Calendar.getInstance(); - - for (int i = 0; i < 3; i++) { - filenames[i] = "output/test3-" + sdf.format(cal.getTime()) + ".gz"; - cal.add(Calendar.SECOND, 1); - } - - filenames[3] = "output/test3-" + sdf.format(cal.getTime()); - - System.out.println("Waiting until next second and 100 millis."); - delayUntilNextSecond(100); - System.out.println("Done waiting."); - - for (int i = 0; i < 5; i++) { - logger.debug("Hello---" + i); - Thread.sleep(500); - } - - for (int i = 0; i < 4; i++) { - //System.out.println(i + " expected filename [" + filenames[i] + "]."); - } - - rfa.close(); - - for (int i = 0; i < 3; i++) { - assertTrue(Compare.gzCompare(filenames[i], "witness/rolling/tbr-test3." + i + ".gz")); - } - - assertTrue(Compare.compare(filenames[3], "witness/rolling/tbr-test3.3")); - } - - /** - * Without compression, activeFileName set, with stop/restart - */ - public void test4() throws Exception { - String datePattern = "yyyy-MM-dd_HH_mm_ss"; - - PatternLayout layout1 = new PatternLayout("%c{1} - %m%n"); - RollingFileAppender rfa1 = new RollingFileAppender(); - rfa1.setLayout(layout1); - - TimeBasedRollingPolicy tbrp1 = new TimeBasedRollingPolicy(); - rfa1.setFile("output/test4.log"); - tbrp1.setFileNamePattern("output/test4-%d{" + datePattern + "}"); - tbrp1.activateOptions(); - rfa1.setRollingPolicy(tbrp1); - rfa1.activateOptions(); - logger.addAppender(rfa1); - - SimpleDateFormat sdf = new SimpleDateFormat(datePattern); - String[] filenames = new String[4]; - - Calendar cal = Calendar.getInstance(); - - for (int i = 0; i < 3; i++) { - filenames[i] = "output/test4-" + sdf.format(cal.getTime()); - cal.add(Calendar.SECOND, 1); - } - filenames[3] = "output/test4.log"; - - System.out.println("Waiting until next second and 100 millis."); - delayUntilNextSecond(100); - System.out.println("Done waiting."); - - for (int i = 0; i <= 2; i++) { - logger.debug("Hello---" + i); - Thread.sleep(500); - } - - logger.removeAppender(rfa1); - rfa1.close(); - - PatternLayout layout2 = new PatternLayout("%c{1} - %m%n"); - RollingFileAppender rfa2 = new RollingFileAppender(); - rfa2.setLayout(layout2); - - TimeBasedRollingPolicy tbrp2 = new TimeBasedRollingPolicy(); - tbrp2.setFileNamePattern("output/test4-%d{" + datePattern + "}"); - rfa2.setFile("output/test4.log"); - tbrp2.activateOptions(); - rfa2.setRollingPolicy(tbrp2); - rfa2.activateOptions(); - logger.addAppender(rfa2); - - for (int i = 3; i <= 4; i++) { - logger.debug("Hello---" + i); - Thread.sleep(500); - } - - rfa2.close(); - - for (int i = 0; i < 4; i++) { - assertTrue(Compare.compare(filenames[i], "witness/rolling/tbr-test4." + i)); - } - } - - /** - * No compression, activeFileName set, without stop/restart - */ - public void test5() throws Exception { - PatternLayout layout = new PatternLayout("%c{1} - %m%n"); - RollingFileAppender rfa = new RollingFileAppender(); - rfa.setLayout(layout); - - String datePattern = "yyyy-MM-dd_HH_mm_ss"; - - TimeBasedRollingPolicy tbrp = new TimeBasedRollingPolicy(); - tbrp.setFileNamePattern("output/test5-%d{" + datePattern + "}"); - rfa.setFile("output/test5.log"); - tbrp.activateOptions(); - rfa.setRollingPolicy(tbrp); - rfa.activateOptions(); - logger.addAppender(rfa); - - SimpleDateFormat sdf = new SimpleDateFormat(datePattern); - String[] filenames = new String[4]; - - Calendar cal = Calendar.getInstance(); - - for (int i = 0; i < 3; i++) { - filenames[i] = "output/test5-" + sdf.format(cal.getTime()); - cal.add(Calendar.SECOND, 1); - } - - filenames[3] = "output/test5.log"; - - System.out.println("Waiting until next second and 100 millis."); - delayUntilNextSecond(100); - System.out.println("Done waiting."); - - for (int i = 0; i < 5; i++) { - logger.debug("Hello---" + i); - Thread.sleep(500); - } - - for (int i = 0; i < 4; i++) { - assertTrue(Compare.compare(filenames[i], "witness/rolling/tbr-test5." + i)); - } - } - - /** - * With compression, activeFileName set, no stop/restart, - */ - public void test6() throws Exception { - PatternLayout layout = new PatternLayout("%c{1} - %m%n"); - RollingFileAppender rfa = new RollingFileAppender(); - rfa.setLayout(layout); - - String datePattern = "yyyy-MM-dd_HH_mm_ss"; - - TimeBasedRollingPolicy tbrp = new TimeBasedRollingPolicy(); - tbrp.setFileNamePattern("output/test6-%d{" + datePattern + "}.gz"); - rfa.setFile("output/test6.log"); - tbrp.activateOptions(); - rfa.setRollingPolicy(tbrp); - rfa.activateOptions(); - logger.addAppender(rfa); - - SimpleDateFormat sdf = new SimpleDateFormat(datePattern); - String[] filenames = new String[4]; - - Calendar cal = Calendar.getInstance(); - - for (int i = 0; i < 3; i++) { - filenames[i] = "output/test6-" + sdf.format(cal.getTime()) + ".gz"; - cal.add(Calendar.SECOND, 1); - } - - filenames[3] = "output/test6.log"; - - System.out.println("Waiting until next second and 100 millis."); - delayUntilNextSecond(100); - System.out.println("Done waiting."); - - for (int i = 0; i < 5; i++) { - logger.debug("Hello---" + i); - Thread.sleep(500); - } - - for (int i = 0; i < 4; i++) { - //System.out.println(i + " expected filename [" + filenames[i] + "]."); - } - - rfa.close(); - - for (int i = 0; i < 3; i++) { - assertTrue(Compare.gzCompare(filenames[i], "witness/rolling/tbr-test6." + i + ".gz")); - } - - assertTrue(Compare.compare(filenames[3], "witness/rolling/tbr-test6.3")); - } - - public void testWithJoran1() throws Exception { - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure("./input/rolling/time1.xml", LogManager.getLoggerRepository()); - jc.dumpErrors(); - - String datePattern = "yyyy-MM-dd_HH_mm_ss"; - - SimpleDateFormat sdf = new SimpleDateFormat(datePattern); - String[] filenames = new String[4]; - - Calendar cal = Calendar.getInstance(); - - for (int i = 0; i < 4; i++) { - filenames[i] = "output/test1-" + sdf.format(cal.getTime()); - cal.add(Calendar.SECOND, 1); - } - - System.out.println("Waiting until next second and 100 millis."); - delayUntilNextSecond(100); - System.out.println("Done waiting."); - - for (int i = 0; i < 5; i++) { - logger.debug("Hello---" + i); - Thread.sleep(500); - } - - for (int i = 0; i < 4; i++) { - //System.out.println(i + " expected filename [" + filenames[i] + "]."); - } - - for (int i = 0; i < 4; i++) { - assertTrue(Compare.compare(filenames[i], "witness/rolling/tbr-test1." + i)); - } - - } - - public void XXXtestWithJoran10() throws Exception { - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure("./input/rolling/time2.xml", LogManager.getLoggerRepository()); - jc.dumpErrors(); - - String datePattern = "yyyy-MM-dd"; - - SimpleDateFormat sdf = new SimpleDateFormat(datePattern); - String[] filenames = new String[0]; - - Calendar cal = Calendar.getInstance(); - - filenames[0] = "output/test1-" + sdf.format(cal.getTime()); - - for (int i = 0; i < 5; i++) { - logger.debug("Hello---" + i); - Thread.sleep(500); - } - - - for (int i = 0; i < 1; i++) { - assertTrue(Compare.compare(filenames[i], "witness/rolling/tbr-test10." + i)); - } - - } - - void delayUntilNextSecond(int millis) { - long now = System.currentTimeMillis(); - Calendar cal = Calendar.getInstance(); - cal.setTime(new Date(now)); - - cal.set(Calendar.MILLISECOND, millis); - cal.add(Calendar.SECOND, 1); - - long next = cal.getTime().getTime(); - - try { - Thread.sleep(next - now); - } catch (Exception e) { - } - } - - void delayUntilNextMinute(int seconds) { - long now = System.currentTimeMillis(); - Calendar cal = Calendar.getInstance(); - cal.setTime(new Date(now)); - - cal.set(Calendar.SECOND, seconds); - cal.add(Calendar.MINUTE, 1); - - long next = cal.getTime().getTime(); - - try { - Thread.sleep(next - now); - } catch (Exception e) { - } - } - -} diff --git a/tests/src/java/org/apache/log4j/rolling/helper/CompressTestCase.java b/tests/src/java/org/apache/log4j/rolling/helper/CompressTestCase.java deleted file mode 100644 index 2892a143fd..0000000000 --- a/tests/src/java/org/apache/log4j/rolling/helper/CompressTestCase.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.rolling.helper; - -import org.apache.log4j.util.Compare; - -import junit.framework.TestCase; -import java.io.File; - -/** - * @author Ceki - - */ -public class CompressTestCase extends TestCase { - - /** - * Constructor for CompressTestCase. - * @param arg0 - */ - public CompressTestCase(String arg0) { - super(arg0); - } - - public void test1() throws Exception { - GZCompressAction.execute(new File("input/compress1.txt"), new File("output/compress1.txt.gz"), false, null); - assertTrue(Compare.gzCompare("output/compress1.txt.gz", - "witness/compress1.txt.gz")); - } - - public void test2() throws Exception { - GZCompressAction.execute(new File("input/compress2.txt"), new File("output/compress2.txt.gz"), false, null); - assertTrue(Compare.gzCompare("output/compress2.txt.gz", - "witness/compress2.txt.gz")); - } - - /* witness file does not exist - public void test3() throws Exception { - ZipCompressAction.execute(new File("input/compress3.txt"), new File("output/compress3.txt.zip"), false, null); - assertTrue(Compare.compare("output/compress3.txt.zip", - "witness/compress3.txt.zip")); - } - */ -} diff --git a/tests/src/java/org/apache/log4j/rolling/helper/FileNamePatternTestCase.java b/tests/src/java/org/apache/log4j/rolling/helper/FileNamePatternTestCase.java deleted file mode 100644 index 3f80e1c774..0000000000 --- a/tests/src/java/org/apache/log4j/rolling/helper/FileNamePatternTestCase.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 1999,2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.rolling.helper; - -import org.apache.log4j.rolling.RollingPolicyBase; -import org.apache.log4j.rolling.RolloverDescription; - -import junit.framework.TestCase; - -import java.util.Calendar; -import org.apache.log4j.ULogger; - - -/** - * Tests for FileNamePattern. - * - * @author Ceki - * @author Curt Arnold - * - */ -public final class FileNamePatternTestCase extends TestCase { - /** - * Construct new test. - * @param name test name - */ - public FileNamePatternTestCase(final String name) { - super(name); - } - - private static class FileNameTestRollingPolicy extends RollingPolicyBase { - public FileNameTestRollingPolicy(final String pattern) { - setFileNamePattern(pattern); - parseFileNamePattern(); - } - - public void activateOptions() { - } - public RolloverDescription initialize(final String activeName, final boolean append) { - return null; - } - public RolloverDescription rollover(final String activeName) { - return null; - } - public ULogger getLogger() { - return null; - } - public String format(Object obj) { - StringBuffer buf = new StringBuffer(); - formatFileName(obj, buf); - return buf.toString(); - } - } - - private void assertDatePattern(final String pattern, final int year, - final int month, final int day, final int hour, final int min, - final String expected) { - Calendar cal = Calendar.getInstance(); - cal.set(year, month, day, hour, min); - FileNameTestRollingPolicy policy = new FileNameTestRollingPolicy(pattern); - assertEquals(expected, - policy.format(cal.getTime())); - } - - private void assertIntegerPattern(final String pattern, final int value, - final String expected) { - FileNameTestRollingPolicy policy = new FileNameTestRollingPolicy(pattern); - assertEquals(expected, policy.format(new Integer(value))); - } - - public void testFormatInteger1() { - assertIntegerPattern("t", 3, "t"); - } - - public void testFormatInteger2() { - assertIntegerPattern("foo", 3, "foo"); - } - - public void testFormatInteger3() { - assertIntegerPattern("foo%", 3, "foo%"); - } - - public void testFormatInteger4() { - assertIntegerPattern("%ifoo", 3, "3foo"); - } - - public void testFormatInteger5() { - assertIntegerPattern("foo%ixixo", 3, "foo3xixo"); - } - - public void testFormatInteger6() { - assertIntegerPattern("foo%i.log", 3, "foo3.log"); - } - - public void testFormatInteger7() { - assertIntegerPattern("foo.%i.log", 3, "foo.3.log"); - } - - public void testFormatInteger8() { - assertIntegerPattern("%ifoo%", 3, "3foo%"); - } - - public void testFormatInteger9() { - assertIntegerPattern("%ifoo%%", 3, "3foo%"); - } - - public void testFormatInteger10() { - assertIntegerPattern("%%foo", 3, "%foo"); - } - - public void testFormatInteger11() { - assertIntegerPattern("foo%ibar%i", 3, "foo3bar3"); - } - - public void testFormatDate1() { - assertDatePattern("foo%d{yyyy.MM.dd}", 2003, 4, 20, 17, 55, - "foo2003.05.20"); - } - - public void testFormatDate2() { - assertDatePattern("foo%d{yyyy.MM.dd HH:mm}", 2003, 4, 20, 17, 55, - "foo2003.05.20 17:55"); - } - - public void testFormatDate3() { - assertDatePattern("%d{yyyy.MM.dd HH:mm} foo", 2003, 4, 20, 17, 55, - "2003.05.20 17:55 foo"); - } - - /** - * A %d is treated as %d{yyyy-MM-dd} if followed by a malformed format specifier. - * - */ - public void testFormatDate4() { - assertDatePattern("foo%dyyyy.MM.dd}", 2003, 4, 20, 17, 55, - "foo2003-05-20yyyy.MM.dd}"); - } - - /** - * A %d is treated as %d{yyyy-MM-dd} if followed by a malformed format specifier. - * - */ - public void testFormatDate5() { - assertDatePattern("foo%d{yyyy.MM.dd", 2003, 4, 20, 17, 55, - "foo2003-05-20{yyyy.MM.dd"); - } - -} diff --git a/tests/src/java/org/apache/log4j/scheduler/CountingJob.java b/tests/src/java/org/apache/log4j/scheduler/CountingJob.java deleted file mode 100644 index d4ad2669ae..0000000000 --- a/tests/src/java/org/apache/log4j/scheduler/CountingJob.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.apache.log4j.scheduler; - -class CountingJob implements Job { - int count = 0; - int id; - long desiredTime; - boolean deleted; - - CountingJob(int id, long scheduledTime) { - this.id = id; - this.desiredTime = scheduledTime; - } - - public void execute() { - if (deleted) { - throw new IllegalStateException(id + "has already been deleted"); - } - - long now = System.currentTimeMillis(); - count++; - - if (now < desiredTime) { - throw new IllegalStateException("Job executed too early."); - } else if ((now - desiredTime) > SchedulerTest.TOLERATED_GAP) { - String msg = - "Job id " + id + " executed " + (now - desiredTime) + " too late "; - System.out.println(msg); - throw new IllegalStateException(msg); - } - } - - void markAsDeleted() { - deleted = true; - } - void sanityCheck(long currentTime) { - } -} - diff --git a/tests/src/java/org/apache/log4j/scheduler/PeriodicJob.java b/tests/src/java/org/apache/log4j/scheduler/PeriodicJob.java deleted file mode 100644 index afd27f971f..0000000000 --- a/tests/src/java/org/apache/log4j/scheduler/PeriodicJob.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.scheduler; - -import java.util.Vector; - - -class PeriodicJob extends CountingJob { - long period; - Vector desiredTimeVector; - Vector actualExecutionTime; - - PeriodicJob(int id, long desiredExecutionTime, long period) { - super(id, desiredExecutionTime); - this.period = period; - actualExecutionTime = new Vector(); - desiredTimeVector = new Vector(); - desiredTimeVector.add(new Long(desiredExecutionTime)); - } - - public void execute() { - if (deleted) { - throw new IllegalStateException(id + "has already been deleted"); - } - - long now = System.currentTimeMillis(); - count++; - - - //System.out.println( - //id + " - execute called: count" + count + ", now=" + now); - long lastDesiredTime = - ((Long) desiredTimeVector.lastElement()).longValue(); - desiredTimeVector.add(new Long(lastDesiredTime + period)); - actualExecutionTime.add(new Long(now)); - - if (now < lastDesiredTime) { - throw new IllegalStateException("Job executed too early."); - } else if ((now - lastDesiredTime) > SchedulerTest.TOLERATED_GAP) { - String msg = - "Job id " + id + " executed " + (now - lastDesiredTime) + " too late "; - System.out.println(msg); - throw new IllegalStateException(msg); - } - } - - void sanityCheck(long currentTime) { - System.out.println("sanity check on job " + id); - - if (!deleted) { - int expectedNumberOfExecutions = - (int) ((currentTime - desiredTime) / period); - - // allow for 15% error margin - if ((actualExecutionTime.size()*1.25) < expectedNumberOfExecutions) { - throw new IllegalStateException( - "Too few executions. Was " + actualExecutionTime.size() - + " expected " + expectedNumberOfExecutions + " period="+period); - } - } - - for (int i = 0; i < actualExecutionTime.size(); i++) { - long actual = ((Long) actualExecutionTime.get(i)).longValue(); - long desired = ((Long) desiredTimeVector.get(i)).longValue(); - - if (actual < desired) { - throw new IllegalStateException("Job executed too early."); - } else if ((actual - desired) > (SchedulerTest.TOLERATED_GAP * (i + 1))) { - String msg = - "Job id " + id + " executed " + (actual - desired) + " too late "; - System.out.println(msg); - throw new IllegalStateException(msg); - } - } - } -} diff --git a/tests/src/java/org/apache/log4j/scheduler/SchedulerTest.java b/tests/src/java/org/apache/log4j/scheduler/SchedulerTest.java deleted file mode 100644 index 7ccba3bdfe..0000000000 --- a/tests/src/java/org/apache/log4j/scheduler/SchedulerTest.java +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.scheduler; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import java.util.Iterator; -import java.util.Random; -import java.util.Vector; - - -/** - * @author Ceki Gulcu - * - */ -public class SchedulerTest extends TestCase { - static final long TOLERATED_GAP = 2000; - Random random = new Random(480361007); - - public SchedulerTest(String arg0) { - super(arg0); - } - - protected void setUp() throws Exception { - super.setUp(); - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - - public void testBasic() { - Scheduler scheduler = new Scheduler(); - scheduler.start(); - - long now = System.currentTimeMillis(); - long expected = now + 100; - CountingJob cj = new CountingJob(0, expected); - scheduler.schedule(cj, expected); - sleep(300); - assertEquals(1, cj.count); - } - - public void testMultipleEvents() { - Vector jobs = new Vector(); - Scheduler scheduler = new Scheduler(); - scheduler.start(); - - long now = System.currentTimeMillis(); - - int loopLength = 100; - - for (int i = 0; i < loopLength; i++) { - long expected = now + (i * 100); - CountingJob cj = new CountingJob(i, expected); - jobs.add(cj); - scheduler.schedule(cj, expected); - } - - sleep((100 * loopLength) + 200); - - for (Iterator i = jobs.iterator(); i.hasNext();) { - CountingJob cj = (CountingJob) i.next(); - assertEquals(1, cj.count); - } - } - - public void testDelete() { - Vector jobs = new Vector(); - Scheduler scheduler = new Scheduler(); - scheduler.start(); - - long now = System.currentTimeMillis(); - - long expected0 = now + 200; - CountingJob cj0 = new CountingJob(0, expected0); - long expected1 = expected0 + 200; - CountingJob cj1 = new CountingJob(1, expected1); - scheduler.schedule(cj0, expected0); - scheduler.schedule(cj1, expected1); - scheduler.delete(cj0); - cj0.markAsDeleted(); - sleep(100 + (3 * 200)); - assertEquals(0, cj0.count); - assertEquals(1, cj1.count); - } - - /** - * A test that inserts and deltes a large number of jobs at random - */ - public void testRandom() { - Scheduler scheduler = new Scheduler(); - scheduler.start(); - - Vector jobVector = new Vector(); - Vector deletedVector = new Vector(); - - // the approximative duration of this test in millisecs - final int TEST_DURATION = 15000; - - // the frequncy of operations in millisecs - final int OP_FREQUENCY = 25; - - // The number of times we will perform an operation on the scheduler - final int MAX_OPS = TEST_DURATION / OP_FREQUENCY; - - long start = System.currentTimeMillis(); - - for (long i = 0; i < MAX_OPS; i++) { - if (shouldDelete() && !jobVector.isEmpty()) { - int indexToDelete = getRandomIndexToDelete(jobVector.size()); - CountingJob j = (CountingJob) jobVector.remove(indexToDelete); - - scheduler.delete(j); - deletedVector.add(j); - j.markAsDeleted(); - } else { - long expected = start + random.nextInt(TEST_DURATION); - CountingJob cj; - - if (shouldBePeriodic()) { - System.out.println(i+ " is periodic"); - // the period should be at least 50 millis - int period = random.nextInt(500)+50; - cj = new PeriodicJob((int) i, expected, period); - jobVector.add(cj); - scheduler.schedule(cj, expected, period); - } else { - cj = new CountingJob((int) i, expected); - jobVector.add(cj); - scheduler.schedule(cj, expected); - } - - } - } - - long loopEnd = System.currentTimeMillis(); - sleep(TEST_DURATION - (loopEnd - start) + 2000); - - long endOfExecution = System.currentTimeMillis(); - - if (deletedVector.size() > (MAX_OPS / 2)) { - fail("too many deleted jobs: " + deletedVector.size()); - } - - if (jobVector.size() < (MAX_OPS / 2)) { - fail("too few jobs: " + jobVector.size()); - } - - for (Iterator i = jobVector.iterator(); i.hasNext();) { - CountingJob cj = (CountingJob) i.next(); - cj.sanityCheck(endOfExecution); - } - - for (Iterator i = deletedVector.iterator(); i.hasNext();) { - CountingJob cj = (CountingJob) i.next(); - cj.sanityCheck(endOfExecution); - } - } - - public void testPeriodic() { - Scheduler scheduler = new Scheduler(); - scheduler.start(); - - long now = System.currentTimeMillis(); - long firstOn = now; - long period = 100; - PeriodicJob pj = new PeriodicJob(0, firstOn, period); - scheduler.schedule(pj, firstOn, period); - - int NUM_PERIODS = 10; - sleep(period * (NUM_PERIODS+1)); - - scheduler.shutdown(); - - long endOfExecution = System.currentTimeMillis(); - - if (pj.count < NUM_PERIODS) { - fail( - "Periodic job executed only " + pj.count + " times. Expected at least" - + NUM_PERIODS); - } - pj.sanityCheck(endOfExecution); - } - - public void testMultiplePeriodic() { - Vector jobs = new Vector(); - Scheduler scheduler = new Scheduler(); - scheduler.start(); - - long now = System.currentTimeMillis(); - long period = 100; - long runLen = 10; - - for (int i = 0; i < runLen; i++) { - long firstOn = now + i; - PeriodicJob pj = new PeriodicJob(i, firstOn, period); - scheduler.schedule(pj, firstOn, period); - jobs.add(pj); - } - - int NUM_PERIODS = 10; - sleep(period * NUM_PERIODS); - scheduler.shutdown(); - - long endOfExecution = System.currentTimeMillis(); - - for (int i = 0; i < runLen; i++) { - PeriodicJob pj = (PeriodicJob) jobs.get(i); - - // allow for 15% error margin - if ((pj.count*1.15) < NUM_PERIODS) { - fail( - "Periodic job executed only " + pj.count - + " times. Expected at least " + NUM_PERIODS); - } - pj.sanityCheck(endOfExecution); - } - } - - boolean shouldDelete() { - int r = random.nextInt(2); - - if (r == 2) { - return true; - } else { - return false; - } - } - - // One in every 10 tests should be periodic - boolean shouldBePeriodic() { - int r = random.nextInt(10); - - if (r == 0) { - return true; - } else { - return false; - } - } - - // On average, make the index of 1 out of 5 deletes zero - int getRandomIndexToDelete(int range) { - int r = random.nextInt(5); - - if (r == 0) { - return 0; - } else { - return random.nextInt(range); - } - } - - void sleep(long duration) { - try { - Thread.sleep(duration); - } catch (InterruptedException ie) { - } - } - - public static Test xsuite() { - TestSuite suite = new TestSuite(); - - suite.addTest(new SchedulerTest("testRandom")); - //suite.addTest(new SchedulerTest("testPeriodic")); - //suite.addTest(new SchedulerTest("testMultiplePeriodic")); - return suite; - } -} diff --git a/tests/src/java/org/apache/log4j/selector/PassByJNDI.java b/tests/src/java/org/apache/log4j/selector/PassByJNDI.java deleted file mode 100644 index cff649e00c..0000000000 --- a/tests/src/java/org/apache/log4j/selector/PassByJNDI.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.apache.log4j.selector; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; - - -import javax.naming.Context; -import javax.naming.InitialContext; - -import org.mortbay.http.SocketListener; - -// In bug #30425, Michael Price asserts that org.mortbay.jetty.Server is -// sufficient. We'll play dumb for the moment. -import org.mortbay.jetty.plus.Server; - - -import junit.framework.TestCase; - -/** - * PassByJNDI studies the effects of passing parameters through JNDI - * - * @author Ceki Gülcü - */ -public class PassByJNDI extends TestCase { - - Server server; - - public PassByJNDI(String arg0) { - super(arg0); - } - - /* - * @see TestCase#setUp() - */ - protected void setUp() throws Exception { - super.setUp(); - - Context ctx = new InitialContext(); - server = new Server(); - SocketListener listener = new SocketListener(); - listener.setPort(8080); - server.addListener(listener); - - server.addWebApplication("localhost", "tata", "./webapps/Tata/tata.war"); - server.addWebApplication("localhost", "titi", "./webapps/Titi/titi.war"); - - server.start(); - } - - protected void tearDown() throws Exception { - super.tearDown(); - server.stop(); - } - - public void test1() throws Exception { - HttpURLConnection connection; - String contents; - - URL urlToto = new URL("http://localhost:8080/tata/XServlet"); - URL urlTiti = new URL("http://localhost:8080/titi/XServlet"); - - connection = (HttpURLConnection) urlToto.openConnection(); - contents = getContents(connection).toString(); - assertEquals("tata", contents.trim()); - - connection = (HttpURLConnection) urlTiti.openConnection(); - contents = getContents(connection).toString(); - assertEquals("titi", contents.trim()); - - } - - StringBuffer getContents(HttpURLConnection connection) throws IOException { - StringBuffer content = new StringBuffer(); - InputStream is = connection.getInputStream(); - - byte[] buffer = new byte[2048]; - int count; - while (-1 != (count = is.read(buffer))) { - content.append(new String(buffer, 0, count)); - } - return content; - } - -} diff --git a/tests/src/java/org/apache/log4j/spi/LocationInfoTest.java b/tests/src/java/org/apache/log4j/spi/LocationInfoTest.java new file mode 100644 index 0000000000..0114876036 --- /dev/null +++ b/tests/src/java/org/apache/log4j/spi/LocationInfoTest.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.spi; + +import junit.framework.TestCase; + +/** + * Tests for LocationInfo. + */ +public class LocationInfoTest extends TestCase { + + /** + * Tests four parameter constructor. + */ + public void testFourParamConstructor() { + final String className = LocationInfoTest.class.getName(); + final String methodName = "testFourParamConstructor"; + final String fileName = "LocationInfoTest.java"; + final String lineNumber = "41"; + LocationInfo li = new LocationInfo(fileName, + className, methodName, lineNumber); + assertEquals(className, li.getClassName()); + assertEquals(methodName, li.getMethodName()); + assertEquals(fileName, li.getFileName()); + assertEquals(lineNumber, li.getLineNumber()); + assertEquals(className + "." + methodName + + "(" + fileName + ":" + lineNumber + ")", + li.fullInfo); + } + + + /** + * Class with name that is a substring of its caller. + */ + private static class NameSubstring { + /** + * Construct a LocationInfo. Location should be immediate caller of this method. + * @return location info. + */ + public static LocationInfo getInfo() { + return new LocationInfo(new Throwable(), NameSubstring.class.getName()); + + } + } + + /** + * Class whose name is contains the name of the class that obtains the LocationInfo. + */ + private static class NameSubstringCaller { + /** + * Construct a locationInfo. Location should be this location. + * @return location info. + */ + public static LocationInfo getInfo() { + return NameSubstring.getInfo(); + } + + } + + /** + * Tests creation of location info when the logger class name + * is a substring of one of the other classes in the stack trace. + * See bug 44888. + */ + public void testLocationInfo() { + LocationInfo li = NameSubstringCaller.getInfo(); + assertEquals(NameSubstringCaller.class.getName(), li.getClassName()); + assertEquals("getInfo", li.getMethodName()); + } + +} diff --git a/tests/src/java/org/apache/log4j/spi/LoggingEventTest.java b/tests/src/java/org/apache/log4j/spi/LoggingEventTest.java index 822a3d7121..9dbec3a520 100644 --- a/tests/src/java/org/apache/log4j/spi/LoggingEventTest.java +++ b/tests/src/java/org/apache/log4j/spi/LoggingEventTest.java @@ -18,19 +18,20 @@ package org.apache.log4j.spi; import junit.framework.TestCase; + import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.MDC; import org.apache.log4j.NDC; -import org.apache.log4j.spi.LocationInfo; import org.apache.log4j.util.SerializationTestHelper; +import org.apache.log4j.Priority; +import org.apache.log4j.Category; /** * Tests LoggingEvent. * * @author Curt Arnold - * @since 1.3 */ public class LoggingEventTest extends TestCase { /** @@ -52,11 +53,11 @@ public void testSerializationSimple() throws Exception { LoggingEvent event = new LoggingEvent( root.getClass().getName(), root, Level.INFO, "Hello, world.", null); - event.prepareForDeferredProcessing(); +// event.prepareForDeferredProcessing(); - int[] skip = new int[] { 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362 }; + int[] skip = new int[] { 352, 353, 354, 355, 356 }; SerializationTestHelper.assertSerializationEquals( - "witness/serialization/simple.bin", event, skip, Integer.MAX_VALUE); + "witness/serialization/simple.bin", event, skip, 237); } /** @@ -71,11 +72,11 @@ public void testSerializationWithException() throws Exception { LoggingEvent event = new LoggingEvent( root.getClass().getName(), root, Level.INFO, "Hello, world.", ex); - event.prepareForDeferredProcessing(); +// event.prepareForDeferredProcessing(); - int[] skip = new int[] { 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 600, 734, 735, 1511 }; + int[] skip = new int[] { 352, 353, 354, 355, 356 }; SerializationTestHelper.assertSerializationEquals( - "witness/serialization/exception.bin", event, skip, 591); + "witness/serialization/exception.bin", event, skip, 237); } /** @@ -89,12 +90,12 @@ public void testSerializationWithLocation() throws Exception { LoggingEvent event = new LoggingEvent( root.getClass().getName(), root, Level.INFO, "Hello, world.", null); - LocationInfo info = event.getLocationInformation(); - event.prepareForDeferredProcessing(); + event.getLocationInformation(); +// event.prepareForDeferredProcessing(); - int[] skip = new int[] { 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362 }; + int[] skip = new int[] { 352, 353, 354, 355, 356 }; SerializationTestHelper.assertSerializationEquals( - "witness/serialization/location.bin", event, skip, 479); + "witness/serialization/location.bin", event, skip, 237); } /** @@ -109,12 +110,12 @@ public void testSerializationNDC() throws Exception { LoggingEvent event = new LoggingEvent( root.getClass().getName(), root, Level.INFO, "Hello, world.", null); - event.prepareForDeferredProcessing(); +// event.prepareForDeferredProcessing(); - int[] skip = new int[] { 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353,354, 355, 356, 357, 358, 359, 360, 361, 362 }; + int[] skip = new int[] { 352, 353, 354, 355, 356 }; SerializationTestHelper.assertSerializationEquals( - "witness/serialization/ndc.bin", event, skip, Integer.MAX_VALUE); - } + "witness/serialization/ndc.bin", event, skip, 237); + } /** * Serialize a logging event with mdc. @@ -128,11 +129,11 @@ public void testSerializationMDC() throws Exception { LoggingEvent event = new LoggingEvent( root.getClass().getName(), root, Level.INFO, "Hello, world.", null); - event.prepareForDeferredProcessing(); +// event.prepareForDeferredProcessing(); - int[] skip = new int[] { 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353,354, 355, 356, 357, 358, 359, 360, 361, 362 }; + int[] skip = new int[] { 352, 353, 354, 355, 356 }; SerializationTestHelper.assertSerializationEquals( - "witness/serialization/mdc.bin", event, skip, Integer.MAX_VALUE); + "witness/serialization/mdc.bin", event, skip, 237); } /** @@ -187,8 +188,8 @@ public void testDeserializationWithLocation() throws Exception { * Tests LoggingEvent.fqnOfCategoryClass. */ public void testFQNOfCategoryClass() { - org.apache.log4j.Category root = Logger.getRootLogger(); - org.apache.log4j.Priority info = Level.INFO; + Category root = Logger.getRootLogger(); + Priority info = Level.INFO; String catName = Logger.class.toString(); LoggingEvent event = new LoggingEvent( @@ -201,16 +202,70 @@ public void testFQNOfCategoryClass() { * @deprecated */ public void testLevel() { - org.apache.log4j.Category root = Logger.getRootLogger(); - org.apache.log4j.Priority info = Level.INFO; + Category root = Logger.getRootLogger(); + Priority info = Level.INFO; String catName = Logger.class.toString(); LoggingEvent event = new LoggingEvent( catName, root, 0L, info, "Hello, world.", null); - org.apache.log4j.Priority error = Level.ERROR; + Priority error = Level.ERROR; event.level = error; assertEquals(Level.ERROR, event.level); } + /** + * Tests LoggingEvent.getLocationInfo() when no FQCN is specified. + * See bug 41186. + */ + public void testLocationInfoNoFQCN() { + Category root = Logger.getRootLogger(); + Priority level = Level.INFO; + LoggingEvent event = + new LoggingEvent( + null, root, 0L, level, "Hello, world.", null); + LocationInfo info = event.getLocationInformation(); + // + // log4j 1.2 returns an object, its layout doesn't check for nulls. + // log4j 1.3 returns a null. + // + assertNotNull(info); + if (info != null) { + assertEquals("?", info.getLineNumber()); + assertEquals("?", info.getClassName()); + assertEquals("?", info.getFileName()); + assertEquals("?", info.getMethodName()); + } + } + + /** + * Message object that throws a RuntimeException on toString(). + * See bug 37182. + */ + private static class BadMessage { + public BadMessage() { + } + + public String toString() { + throw new RuntimeException(); + } + } + + /** + * Tests that an runtime exception or error during toString + * on the message parameter does not propagate to caller. + * See bug 37182. + */ + public void testBadMessage() { + Category root = Logger.getRootLogger(); + Priority info = Level.INFO; + String catName = Logger.class.toString(); + BadMessage msg = new BadMessage(); + LoggingEvent event = + new LoggingEvent( + catName, root, 0L, info, msg, null); + // would result in exception in earlier versions + event.getRenderedMessage(); + } + } diff --git a/tests/src/java/org/apache/log4j/spi/ThrowableInformationTest.java b/tests/src/java/org/apache/log4j/spi/ThrowableInformationTest.java index 20d542abdf..e2ad1cb378 100644 --- a/tests/src/java/org/apache/log4j/spi/ThrowableInformationTest.java +++ b/tests/src/java/org/apache/log4j/spi/ThrowableInformationTest.java @@ -5,77 +5,41 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.log4j.spi; import junit.framework.TestCase; import java.io.PrintWriter; + /** - * - * @author Ceki Gülcü - * + * Unit tests for ThrowableInformation. */ public class ThrowableInformationTest extends TestCase { - /* - * @see TestCase#setUp() - */ - protected void setUp() throws Exception { - super.setUp(); - } - - /* - * @see TestCase#tearDown() - */ - protected void tearDown() throws Exception { - super.tearDown(); - } - - /* - * Class to test for boolean equals(Object) - */ - public void testEqualsObject() { - Throwable e1 = new Exception("exeption 1"); - Throwable e2 = new Exception("exeption 2"); - - ThrowableInformation te1 = new ThrowableInformation(e1); - ThrowableInformation te2 = new ThrowableInformation(e2); - - assertEquals(te1, te1); - assertEquals(te2, te2); - - boolean eq1 = te1.equals(te2); - assertEquals(false, eq1); - - boolean eq2 = te1.equals(null); - assertEquals(false, eq2); - - assertEquals(te1.hashCode(), te1.hashCode()); - assertEquals(te2.hashCode(), te2.hashCode()); - } - /** - * @param arg0 - */ - public ThrowableInformationTest(String arg0) - { - super(arg0); - } + /** + * Create ThrowableInformationTest. + * + * @param name test name. + */ + public ThrowableInformationTest(final String name) { + super(name); + } /** * Custom throwable that only calls methods * overridden by VectorWriter in log4j 1.2.14 and earlier. */ private static final class OverriddenThrowable extends Throwable { + private static final long serialVersionUID = 1L; /** * Create new instance. */ @@ -119,6 +83,7 @@ public void testOverriddenBehavior() { * not overridden by VectorWriter in log4j 1.2.14 and earlier. */ private static final class NotOverriddenThrowable extends Throwable { + private static final long serialVersionUID = 1L; /** * Create new instance. */ @@ -176,6 +141,7 @@ public void testNotOverriddenBehavior() { * with null. */ private static final class NullThrowable extends Throwable { + private static final long serialVersionUID = 1L; /** * Create new instance. */ @@ -213,6 +179,7 @@ public void testNull() { * Custom throwable that does nothing in printStackTrace. */ private static final class EmptyThrowable extends Throwable { + private static final long serialVersionUID = 1L; /** * Create new instance. */ @@ -243,6 +210,7 @@ public void testEmpty() { * Custom throwable that emits a specified string in printStackTrace. */ private static final class StringThrowable extends Throwable { + private static final long serialVersionUID = 1L; /** * Stack trace. */ @@ -314,7 +282,6 @@ public void testLineFeedBlank() { /** * Test that getThrowable returns the throwable provided to the constructor. - * @deprecated */ public void testGetThrowable() { Throwable t = new StringThrowable("Hello, World"); @@ -322,5 +289,55 @@ public void testGetThrowable() { assertSame(t, ti.getThrowable()); } + /** + * Tests isolation of returned string representation + * from internal state of ThrowableInformation. + * log4j 1.2.15 and earlier did not isolate initial call. + * See bug 44032. + */ + public void testIsolation() { + ThrowableInformation ti = new ThrowableInformation( + new StringThrowable("Hello, World")); + String[] rep = ti.getThrowableStrRep(); + assertEquals("Hello, World", rep[0]); + rep[0] = "Bonjour, Monde"; + String[] rep2 = ti.getThrowableStrRep(); + assertEquals("Hello, World", rep2[0]); + } + + /** + * Custom throwable that throws a runtime exception + * when printStackTrace is called. + */ + private static final class NastyThrowable extends Throwable { + private static final long serialVersionUID = 1L; + /** + * Create new instance. + */ + public NastyThrowable() { + } + + /** + * Print stack trace. + * + * @param s print writer. + */ + public void printStackTrace(final PrintWriter s) { + s.print("NastyException"); + throw new RuntimeException("Intentional exception"); + } + } + + /** + * Tests that a failure in printStackTrace + * does not percolate out of getThrowableStrRep(). + * + */ + public void testNastyException() { + ThrowableInformation ti = new ThrowableInformation( + new NastyThrowable()); + String[] rep = ti.getThrowableStrRep(); + assertEquals("NastyException", rep[0]); + } - } +} diff --git a/tests/src/java/org/apache/log4j/spi/location/LocationInfoTest.java b/tests/src/java/org/apache/log4j/spi/location/LocationInfoTest.java deleted file mode 100644 index af09091e64..0000000000 --- a/tests/src/java/org/apache/log4j/spi/location/LocationInfoTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.spi.location; - -import org.apache.log4j.BasicConfigurator; -import org.apache.log4j.Level; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.spi.LocationInfo; - -import junit.framework.TestCase; - -/** - * - * Very simple test verifying that LocationInfo extraction works, at least in - * simple cases. - * - * Note that this test is indetation sensitive. See lines commented as - * "LINE NUMBER:" - * - * @author Ceki - */ -public class LocationInfoTest extends TestCase { - - Logger logger = Logger.getLogger(LocationInfoTest.class); - - /* - * @see TestCase#setUp() - */ - protected void setUp() throws Exception { - super.setUp(); - BasicConfigurator.configure(); - } - - /* - * @see TestCase#tearDown() - */ - protected void tearDown() throws Exception { - super.tearDown(); - LogManager.shutdown(); - } - - /** - * Constructor for LocationInfoTest. - * @param arg0 - */ - public LocationInfoTest(String arg0) { - super(arg0); - } - - /* - * Class to test for boolean equals(Object) - */ - public void testEqualsObject() { - - Throwable t1 = new Throwable(); - Throwable t2 = new Throwable(); - - - LoggingEvent le = new LoggingEvent("org.apache.log4j.spi.LoggingEvent", logger, Level.DEBUG, - "toto", null); - - // LINE NUMBER: line extraction is done from on line 79 (following line) - LocationInfo li = le.getLocationInformation(); - - if(li == LocationInfo.NA_LOCATION_INFO) { - fail("For regular events, location info should not be LocationInfo.NA_LOCATION_INFO "); - } - - assertEquals(this.getClass().getName(), li.getClassName()); - assertEquals("LocationInfoTest.java", li.getFileName()); - // LINE NUMBER: change the following number if lines are moved - assertEquals("79", li.getLineNumber()); - assertEquals("testEqualsObject", li.getMethodName()); - - /*ThrowableInformation te1 = new ThrowableInformation(e1); - ThrowableInformation te2 = new ThrowableInformation(e2); - - assertEquals(te1, te1); - assertEquals(te2, te2); - - boolean eq1 = te1.equals(te2); - assertEquals(false, eq1); - - boolean eq2 = te1.equals(null); - assertEquals(false, eq2); - */ - } - -} diff --git a/tests/src/java/org/apache/log4j/stressCategory b/tests/src/java/org/apache/log4j/stressCategory index 30833c0c9d..ce58c008e8 100644 --- a/tests/src/java/org/apache/log4j/stressCategory +++ b/tests/src/java/org/apache/log4j/stressCategory @@ -1,3 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. # ==================================================== function stressTest { java org.apache.log4j.StressCategory $* diff --git a/tests/src/java/org/apache/log4j/stressCategory.pl b/tests/src/java/org/apache/log4j/stressCategory.pl index 875d2ca6d3..98bd67781b 100644 --- a/tests/src/java/org/apache/log4j/stressCategory.pl +++ b/tests/src/java/org/apache/log4j/stressCategory.pl @@ -1,3 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. # This perl script all combinations of tree structures based on the "args" # array. diff --git a/tests/src/java/org/apache/log4j/util/AbsoluteDateAndTimeFilter.java b/tests/src/java/org/apache/log4j/util/AbsoluteDateAndTimeFilter.java index 0373295b8b..ae4a675784 100644 --- a/tests/src/java/org/apache/log4j/util/AbsoluteDateAndTimeFilter.java +++ b/tests/src/java/org/apache/log4j/util/AbsoluteDateAndTimeFilter.java @@ -17,18 +17,19 @@ package org.apache.log4j.util; -import org.apache.oro.text.perl.Perl5Util; +import org.apache.oro.text.perl.Perl5Util; public class AbsoluteDateAndTimeFilter implements Filter { - Perl5Util util = new Perl5Util(); - public String filter(String in) { - String pat = "/" + Filter.ABSOLUTE_DATE_AND_TIME_PAT + "/"; + Perl5Util util = new Perl5Util(); + + public + String filter(String in) { + String pat = "/"+Filter.ABSOLUTE_DATE_AND_TIME_PAT+"/"; - if (util.match(pat, in)) { - return util.substitute( - "s/" + Filter.ABSOLUTE_DATE_AND_TIME_PAT + "//", in); + if(util.match(pat, in)) { + return util.substitute("s/"+Filter.ABSOLUTE_DATE_AND_TIME_PAT+"//", in); } else { return in; } diff --git a/tests/src/java/org/apache/log4j/util/AbsoluteTimeFilter.java b/tests/src/java/org/apache/log4j/util/AbsoluteTimeFilter.java index fce58ed593..770868a84b 100644 --- a/tests/src/java/org/apache/log4j/util/AbsoluteTimeFilter.java +++ b/tests/src/java/org/apache/log4j/util/AbsoluteTimeFilter.java @@ -17,16 +17,19 @@ package org.apache.log4j.util; + import org.apache.oro.text.perl.Perl5Util; public class AbsoluteTimeFilter implements Filter { - Perl5Util util = new Perl5Util(); - public String filter(String in) { - String pat = "/" + Filter.ABSOLUTE_TIME_PAT + "/"; + Perl5Util util = new Perl5Util(); + + public + String filter(String in) { + String pat = "/"+Filter.ABSOLUTE_TIME_PAT+"/"; - if (util.match(pat, in)) { - return util.substitute("s/" + Filter.ABSOLUTE_TIME_PAT + "//", in); + if(util.match(pat, in)) { + return util.substitute("s/"+Filter.ABSOLUTE_TIME_PAT+"//", in); } else { return in; } diff --git a/tests/src/java/org/apache/log4j/util/BinaryCompare.java b/tests/src/java/org/apache/log4j/util/BinaryCompare.java deleted file mode 100644 index 4864c9cc18..0000000000 --- a/tests/src/java/org/apache/log4j/util/BinaryCompare.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.util; - -import java.io.BufferedInputStream; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; - - -public final class BinaryCompare { - /** - * Class can not be constructed. - */ - private BinaryCompare() { - } - - /** - * Compares two files using binary comparison. - * - * @param file1 - * @param file2 - * @return true if they are the same - * @throws FileNotFoundException - * @throws IOException - */ - public static boolean compare(final String file1, final String file2) - throws FileNotFoundException, IOException { - BufferedInputStream in1 = new BufferedInputStream(new FileInputStream( - file1)); - BufferedInputStream in2 = new BufferedInputStream(new FileInputStream( - file2)); - try { - return compare(file1, file2, in1, in2); - } finally { - in1.close(); - in2.close(); - } - - } - - private static boolean compare(final String file1, final String file2, InputStream in1, InputStream in2) throws IOException { - int byte1 = 0; - int byte2 = 0; - - for (int pos = 0; byte1 != -1; pos++) { - byte1 = in1.read(); - byte2 = in2.read(); - - if (byte1 != byte2) { - if (byte2 == -1) { - System.out.println("File [" + file2 + - "] longer than file [" + file1 + "]."); - } else if (byte1 == -1) { - System.out.println("File [" + file1 + - "] longer than file [" + file2 + "]."); - } else { - System.out.println("Files differ at offset " + pos + ": [" + - file1 + "] has " + Integer.toHexString(byte1) + ", [" + - file2 + "] has " + Integer.toHexString(byte2) + "."); - } - - return false; - } - } - - return true; - } -} diff --git a/tests/src/java/org/apache/log4j/util/Compare.java b/tests/src/java/org/apache/log4j/util/Compare.java index b97edefba6..9d8ff710aa 100644 --- a/tests/src/java/org/apache/log4j/util/Compare.java +++ b/tests/src/java/org/apache/log4j/util/Compare.java @@ -18,31 +18,87 @@ package org.apache.log4j.util; import java.io.BufferedReader; -import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; +import java.io.FileInputStream; +import java.io.InputStream; import java.io.InputStreamReader; -import java.util.zip.GZIPInputStream; +import java.io.File; public class Compare { + static final int B1_NULL = -1; static final int B2_NULL = -2; - - public static boolean compare(String file1, String file2) - throws FileNotFoundException, IOException { + + static + public + boolean compare(String file1, String file2) throws FileNotFoundException, + IOException { BufferedReader in1 = new BufferedReader(new FileReader(file1)); BufferedReader in2 = new BufferedReader(new FileReader(file2)); + + String s1; + int lineCounter = 0; + while((s1 = in1.readLine()) != null) { + lineCounter++; + String s2 = in2.readLine(); + if(!s1.equals(s2)) { + System.out.println("Files ["+file1+"] and ["+file2+"] differ on line " + +lineCounter); + System.out.println("One reads: ["+s1+"]."); + System.out.println("Other reads:["+s2+"]."); + return false; + } + } + + // the second file is longer + if(in2.read() != -1) { + System.out.println("File ["+file2+"] longer than file ["+file1+"]."); + return false; + } + + return true; + } + +private static final InputStream open( + final Class testClass, + final String fileName) throws IOException { + String resourceName = fileName; + if (fileName.startsWith("witness/")) { + resourceName = fileName.substring(fileName.lastIndexOf('/') + 1); + } + InputStream is = testClass.getResourceAsStream(resourceName); + if (is == null) { + File file = new File(fileName); + if (file.exists()) { + is = new FileInputStream(file); + } else { + throw new FileNotFoundException("Resource " + + resourceName + " not found"); + } + } + return is; + } + + public static boolean compare(Class testClass, + final String file1, + final String file2) + throws IOException { + BufferedReader in1 = new BufferedReader(new FileReader(file1)); + BufferedReader in2 = new BufferedReader(new InputStreamReader( + open(testClass, file2))); try { - return compare(file1, file2, in1, in2); + return compare(testClass, file1, file2, in1, in2); } finally { in1.close(); in2.close(); } } - public static boolean compare(String file1, String file2, BufferedReader in1, BufferedReader in2) throws IOException { + public static boolean compare( + Class testClass, String file1, String file2, BufferedReader in1, BufferedReader in2) throws IOException { String s1; int lineCounter = 0; @@ -58,8 +114,8 @@ public static boolean compare(String file1, String file2, BufferedReader in1, Bu + lineCounter); System.out.println("One reads: [" + s1 + "]."); System.out.println("Other reads:[" + s2 + "]."); - outputFile(file1); - outputFile(file2); + outputFile(testClass, file1); + outputFile(testClass, file2); return false; } @@ -69,8 +125,8 @@ public static boolean compare(String file1, String file2, BufferedReader in1, Bu if (in2.read() != -1) { System.out.println( "File [" + file2 + "] longer than file [" + file1 + "]."); - outputFile(file1); - outputFile(file2); + outputFile(testClass, file1); + outputFile(testClass, file2); return false; } @@ -83,9 +139,10 @@ public static boolean compare(String file1, String file2, BufferedReader in1, Bu * Prints file on the console. * */ - private static void outputFile(String file) - throws FileNotFoundException, IOException { - BufferedReader in1 = new BufferedReader(new FileReader(file)); + private static void outputFile(Class testClass, String file) + throws IOException { + InputStream is = open(testClass, file); + BufferedReader in1 = new BufferedReader(new InputStreamReader(is)); String s1; int lineCounter = 0; @@ -110,52 +167,6 @@ private static void outputFile(String file) } in1.close(); } - - public static boolean gzCompare(String file1, String file2) - throws FileNotFoundException, IOException { - BufferedReader in1 = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(file1)))); - BufferedReader in2 = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(file2)))); - try { - return gzCompare(file1, file2, in1, in2); - } finally { - in1.close(); - in2.close(); - } - } - - public static boolean gzCompare(String file1, String file2, BufferedReader in1, BufferedReader in2) throws IOException { - - String s1; - int lineCounter = 0; - - while ((s1 = in1.readLine()) != null) { - lineCounter++; - - String s2 = in2.readLine(); - if (!s1.equals(s2)) { - System.out.println( - "Files [" + file1 + "] and [" + file2 + "] differ on line " - + lineCounter); - System.out.println("One reads: [" + s1 + "]."); - System.out.println("Other reads:[" + s2 + "]."); - outputFile(file1); - outputFile(file2); - - return false; - } - } - - // the second file is longer - if (in2.read() != -1) { - System.out.println( - "File [" + file2 + "] longer than file [" + file1 + "]."); - outputFile(file1); - outputFile(file2); - - return false; - } - - return true; - } + } diff --git a/tests/src/java/org/apache/log4j/util/ControlFilter.java b/tests/src/java/org/apache/log4j/util/ControlFilter.java index 969e3d655c..821d104378 100644 --- a/tests/src/java/org/apache/log4j/util/ControlFilter.java +++ b/tests/src/java/org/apache/log4j/util/ControlFilter.java @@ -19,26 +19,27 @@ import org.apache.oro.text.perl.Perl5Util; - public class ControlFilter implements Filter { + Perl5Util util = new Perl5Util(); + String[] allowedPatterns; public ControlFilter(String[] allowedPatterns) { this.allowedPatterns = allowedPatterns; } - public String filter(String in) throws UnexpectedFormatException { + public + String filter(String in) throws UnexpectedFormatException{ int len = allowedPatterns.length; - - for (int i = 0; i < len; i++) { + for(int i = 0; i < len; i++) { //System.out.println("["+allowedPatterns[i]+"]"); - if (util.match("/" + allowedPatterns[i] + "/", in)) { - //System.out.println("["+in+"] matched ["+allowedPatterns[i]); - return in; - } + if(util.match("/"+allowedPatterns[i]+"/", in)) { + //System.out.println("["+in+"] matched ["+allowedPatterns[i]); + return in; + } } - throw new UnexpectedFormatException("[" + in + "]"); + throw new UnexpectedFormatException("["+in+"]"); } } diff --git a/tests/src/java/org/apache/log4j/util/EnhancedJunitTestRunnerFilter.java b/tests/src/java/org/apache/log4j/util/EnhancedJunitTestRunnerFilter.java new file mode 100644 index 0000000000..af85c3f5d3 --- /dev/null +++ b/tests/src/java/org/apache/log4j/util/EnhancedJunitTestRunnerFilter.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.util; + +import org.apache.oro.text.perl.Perl5Util; + + +public class EnhancedJunitTestRunnerFilter implements Filter { + private Perl5Util util = new Perl5Util(); + + private static final String[] PATTERNS = { + "at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner", + "at org.apache.tools.ant", + "at junit.textui.TestRunner", + "at com.intellij.rt.execution.junit", + "at java.lang.reflect.Method.invoke", + "at org.apache.maven.", + "at org.codehaus.", + "at org.junit.internal.runners.", + "at junit.framework.JUnit4TestAdapter" + }; + + public EnhancedJunitTestRunnerFilter() { + } + + /** + * Filter out stack trace lines coming from the various JUnit TestRunners. + */ + public String filter(String in) { + if (in == null) { + return null; + } + + // + // restore the one instance of Method.invoke that we actually want + // + if (in.indexOf("at junit.framework.TestCase.runTest") != -1) { + return "\tat java.lang.reflect.Method.invoke(X)\n\t" + in.trim(); + } + + for (int i = 0; i < PATTERNS.length; i++) { + if(in.indexOf(PATTERNS[i]) != -1) { + return null; + } + } + if (util.match("/\\sat /", in)) { + return "\t" + in.trim(); + } + return in; + } +} diff --git a/tests/src/java/org/apache/log4j/util/EnhancedLineNumberFilter.java b/tests/src/java/org/apache/log4j/util/EnhancedLineNumberFilter.java new file mode 100644 index 0000000000..0b919538b2 --- /dev/null +++ b/tests/src/java/org/apache/log4j/util/EnhancedLineNumberFilter.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.util; + +import java.util.regex.Pattern; + + +public class EnhancedLineNumberFilter implements Filter { + private Pattern linePattern; + private Pattern nativePattern; + + public EnhancedLineNumberFilter() { + linePattern = Pattern.compile("\\(.*:\\d{1,4}\\)"); + nativePattern = Pattern.compile("\\(Native Method\\)"); + } + + public String filter(final String in) { + + if (linePattern.matcher(in).find()) { + return linePattern.matcher(in).replaceAll("(X)"); + } else if (nativePattern.matcher(in).find()) { + return nativePattern.matcher(in).replaceAll("(X)"); + } else { + return in; + } + } +} diff --git a/tests/src/java/org/apache/log4j/util/Filter.java b/tests/src/java/org/apache/log4j/util/Filter.java index d7da9ff049..76be7d2690 100644 --- a/tests/src/java/org/apache/log4j/util/Filter.java +++ b/tests/src/java/org/apache/log4j/util/Filter.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -18,23 +18,21 @@ package org.apache.log4j.util; public interface Filter { + + final String BASIC_PAT = "\\[main\\] (FATAL|ERROR|WARN|INFO|DEBUG)"; + final String ISO8601_PAT = "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3}"; + // 06 avr. 2002 18:36:32,036 // 18 fevr. 2002 20:05:36,222 - public static final String ABSOLUTE_DATE_AND_TIME_PAT = - "^\\d{1,2} .{2,6}\\.? 200\\d \\d{2}:\\d{2}:\\d{2},\\d{3}"; + static public final String ABSOLUTE_DATE_AND_TIME_PAT = + "^\\d{1,2} .{2,6}\\.? 2\\d{3} \\d{2}:\\d{2}:\\d{2},\\d{3}"; // 18:54:19,201 - public static final String ABSOLUTE_TIME_PAT = - "^\\d{2}:\\d{2}:\\d{2},\\d{3}"; - public static final String RELATIVE_TIME_PAT = "^\\d{1,10}"; - final String BASIC_PAT = "\\[main\\] (FATAL|ERROR|WARN|INFO|DEBUG)"; - final String ISO8601_PAT = - "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3}"; + static public final String ABSOLUTE_TIME_PAT = + "^\\d{2}:\\d{2}:\\d{2},\\d{3}"; + + static public final String RELATIVE_TIME_PAT = "^\\d{1,10}"; + - /** - * This filter transforms the input string and returns the results as - * output. If the input should be ignored, this method returns null. - * - */ String filter(String in) throws UnexpectedFormatException; } diff --git a/tests/src/java/org/apache/log4j/util/ISO8601Filter.java b/tests/src/java/org/apache/log4j/util/ISO8601Filter.java index 3b8682641e..50479f65fa 100644 --- a/tests/src/java/org/apache/log4j/util/ISO8601Filter.java +++ b/tests/src/java/org/apache/log4j/util/ISO8601Filter.java @@ -19,15 +19,16 @@ import org.apache.oro.text.perl.Perl5Util; - public class ISO8601Filter implements Filter { - Perl5Util util = new Perl5Util(); - public String filter(String in) { - String pat = "/" + ISO8601_PAT + "/"; + Perl5Util util = new Perl5Util(); + + public + String filter(String in) { + String pat = "/"+ISO8601_PAT +"/"; - if (util.match(pat, in)) { - return util.substitute("s/" + ISO8601_PAT + "//", in); + if(util.match(pat, in)) { + return util.substitute("s/"+ISO8601_PAT+"//", in); } else { return in; } diff --git a/tests/src/java/org/apache/log4j/util/JunitTestRunnerFilter.java b/tests/src/java/org/apache/log4j/util/JunitTestRunnerFilter.java index 85b9d50f91..809c54d9fc 100644 --- a/tests/src/java/org/apache/log4j/util/JunitTestRunnerFilter.java +++ b/tests/src/java/org/apache/log4j/util/JunitTestRunnerFilter.java @@ -37,18 +37,22 @@ public String filter(String in) { return null; } else if ( util.match( - "/at com.intellij/", + "/at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner/", in)) { return null; } else if ( util.match( - "/at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner/", + "/at com.intellij/", in)) { return null; } else if (in.indexOf("at junit.") >= 0 && in.indexOf("ui.TestRunner") >= 0) { return null; } else if (in.indexOf("org.apache.maven") >= 0) { return null; + } else if(in.indexOf("junit.internal") >= 0) { + return null; + } else if(in.indexOf("JUnit4TestAdapter") >= 0) { + return null; } else if (util.match("/\\sat /", in)) { return "\t" + in.trim(); } else { diff --git a/tests/src/java/org/apache/log4j/util/LineNumberFilter.java b/tests/src/java/org/apache/log4j/util/LineNumberFilter.java index 91b8ded635..c47b9b7a3a 100644 --- a/tests/src/java/org/apache/log4j/util/LineNumberFilter.java +++ b/tests/src/java/org/apache/log4j/util/LineNumberFilter.java @@ -19,16 +19,18 @@ import org.apache.oro.text.perl.Perl5Util; - public class LineNumberFilter implements Filter { + Perl5Util util = new Perl5Util(); - public String filter(String in) { - if (util.match("/\\(.*:\\d{1,4}\\)/", in)) { - return util.substitute("s/\\(.*:\\d{1,4}\\)/\\(X\\)/", in); - } else if (util.match("/\\(Native Method\\)/", in)) { - return util.substitute("s/\\(Native Method\\)/\\(X\\)/", in); + public + String filter(String in) { + if(util.match("/\\(.*:\\d{1,4}\\)/", in)) { + return util.substitute("s/:\\d{1,4}\\)/:XXX)/", in); } else { + if(in.indexOf(", Compiled Code") >= 0) { + return util.substitute("s/, Compiled Code/:XXX/", in); + } return in; } } diff --git a/tests/src/java/org/apache/log4j/util/RelativeTimeFilter.java b/tests/src/java/org/apache/log4j/util/RelativeTimeFilter.java index fb92f31e2d..94d6d0eb09 100644 --- a/tests/src/java/org/apache/log4j/util/RelativeTimeFilter.java +++ b/tests/src/java/org/apache/log4j/util/RelativeTimeFilter.java @@ -19,16 +19,17 @@ import org.apache.oro.text.perl.Perl5Util; - public class RelativeTimeFilter implements Filter { - Perl5Util util = new Perl5Util(); - public String filter(String in) { - String pat = "/" + Filter.RELATIVE_TIME_PAT + "/"; + Perl5Util util = new Perl5Util(); + + public + String filter(String in) { + String pat = "/"+Filter.RELATIVE_TIME_PAT+"/"; - if (util.match(pat, in)) { + if(util.match(pat, in)) { //System.out.println("Removing relative time from line ["+in+"]"); - return util.substitute("s/" + Filter.RELATIVE_TIME_PAT + "//", in); + return util.substitute("s/"+Filter.RELATIVE_TIME_PAT+"//", in); } else { return in; } diff --git a/tests/src/java/org/apache/log4j/util/SerializationTestHelper.java b/tests/src/java/org/apache/log4j/util/SerializationTestHelper.java index 264c175e93..f592a83421 100644 --- a/tests/src/java/org/apache/log4j/util/SerializationTestHelper.java +++ b/tests/src/java/org/apache/log4j/util/SerializationTestHelper.java @@ -116,7 +116,10 @@ public static void assertStreamEquals( FileInputStream is = new FileInputStream(witnessFile); int bytesRead = is.read(expected); is.close(); - TestCase.assertEquals(bytesRead, actual.length); + + if(bytesRead < endCompare) { + TestCase.assertEquals(bytesRead, actual.length); + } int endScan = actual.length; diff --git a/tests/src/java/org/apache/log4j/util/SunReflectFilter.java b/tests/src/java/org/apache/log4j/util/SunReflectFilter.java index 0a694a804f..ddb62d807f 100644 --- a/tests/src/java/org/apache/log4j/util/SunReflectFilter.java +++ b/tests/src/java/org/apache/log4j/util/SunReflectFilter.java @@ -20,7 +20,7 @@ import org.apache.oro.text.perl.Perl5Util; /** - * The sun.reflect.* lines are not present in all JDKs. + * The sun.reflect.* and java.lang.reflect.* lines are not present in all JDKs. * * @author Ceki Gulcu */ @@ -33,8 +33,18 @@ public String filter(String in) { } if (util.match("/at sun.reflect/", in)) { return null; - } else { - return in; } + if (in.indexOf("at java.lang.reflect.") >= 0) { + return null; + } + if (in.indexOf("Compiled Code") >= 0) { + if(in.indexOf("junit.framework.TestSuite") >= 0) { + return util.substitute("s/Compiled Code/TestSuite.java:XXX/", in); + } + } + if (util.match("/\\(Method.java:.*\\)/", in)) { + return util.substitute("s/\\(Method.java:.*\\)/(Native Method)/", in); + } + return in; } } diff --git a/tests/src/java/org/apache/log4j/util/Transformer.java b/tests/src/java/org/apache/log4j/util/Transformer.java index b92339629b..713f29d3bf 100644 --- a/tests/src/java/org/apache/log4j/util/Transformer.java +++ b/tests/src/java/org/apache/log4j/util/Transformer.java @@ -18,7 +18,6 @@ package org.apache.log4j.util; import java.io.BufferedReader; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; @@ -28,52 +27,40 @@ public class Transformer { public static - void transform(String in, String out, Filter[] filters) throws FileNotFoundException, - IOException, + void transform(String in, String out, Filter[] filters) throws IOException, UnexpectedFormatException { String line; BufferedReader input = new BufferedReader(new FileReader(in)); PrintStream output = new PrintStream(new FileOutputStream(out, false)); - try { - // Initialization of input and output omitted - while ((line = input.readLine()) != null) { - // apply all filters - for (int i = 0; i < filters.length; i++) { - line = filters[i].filter(line); - } - if (line != null) { - output.println(line); - } + // Initialization of input and output omitted + while((line = input.readLine()) != null) { + // apply all filters + for(int i = 0; i < filters.length; i++) { + line = filters[i].filter(line); } - } finally { - input.close(); - output.close(); - } + if(line != null) { + output.println(line); + } + } } public static - void transform(String in, String out, Filter filter) throws FileNotFoundException, - IOException, + void transform(String in, String out, Filter filter) throws IOException, UnexpectedFormatException { String line; BufferedReader input = new BufferedReader(new FileReader(in)); PrintStream output = new PrintStream(new FileOutputStream(out)); - try { - // Initialization of input and output omitted - while((line = input.readLine()) != null) { - line = filter.filter(line); - output.println(line); - } - } finally { - input.close(); - output.close(); + // Initialization of input and output omitted + while((line = input.readLine()) != null) { + line = filter.filter(line); + output.println(line); } } diff --git a/tests/src/java/org/apache/log4j/util/UnexpectedFormatException.java b/tests/src/java/org/apache/log4j/util/UnexpectedFormatException.java index 0cda8c809f..8ab79ff8b1 100644 --- a/tests/src/java/org/apache/log4j/util/UnexpectedFormatException.java +++ b/tests/src/java/org/apache/log4j/util/UnexpectedFormatException.java @@ -18,6 +18,7 @@ package org.apache.log4j.util; public class UnexpectedFormatException extends Exception { + private static final long serialVersionUID = 1787725660780924147L; public UnexpectedFormatException(String msg) { super(msg); diff --git a/tests/src/java/org/apache/log4j/util/XMLLineAttributeFilter.java b/tests/src/java/org/apache/log4j/util/XMLLineAttributeFilter.java index 101caf9649..877b432717 100644 --- a/tests/src/java/org/apache/log4j/util/XMLLineAttributeFilter.java +++ b/tests/src/java/org/apache/log4j/util/XMLLineAttributeFilter.java @@ -19,17 +19,15 @@ import org.apache.oro.text.perl.Perl5Util; - public class XMLLineAttributeFilter implements Filter { + Perl5Util util = new Perl5Util(); - public String filter(String in) { - if(in == null) { - return null; - } - if (util.match("/line=\"\\d{1,3}\"/", in)) { + public + String filter(String in) { + if(util.match("/line=\"\\d{1,3}\"/", in)) { return util.substitute("s/line=\"\\d{1,3}\"/line=\"X\"/", in); - } else if (util.match("/line=\"?\"/", in)) { + } else if(util.match("/line=\"?\"/", in)) { return util.substitute("s/line=\"?\"/line=\"X\"/", in); } else { return in; diff --git a/tests/src/java/org/apache/log4j/util/XMLSequenceNumberFilter.java b/tests/src/java/org/apache/log4j/util/XMLSequenceNumberFilter.java deleted file mode 100644 index 390d3a2f6b..0000000000 --- a/tests/src/java/org/apache/log4j/util/XMLSequenceNumberFilter.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.util; - -import org.apache.oro.text.perl.Perl5Util; - - -public class XMLSequenceNumberFilter implements Filter { - Perl5Util util = new Perl5Util(); - - /** - * If the input string contains the pattern 'sequenceNumber="123"', then - * replace the number 123 by XXX and return the result. - */ - public String filter(String in) { - if(in == null) { - return null; - } - if (util.match("/sequenceNumber=\"\\d{1,13}\"/", in)) { - return util.substitute( - "s/sequenceNumber=\"\\d{1,13}\"/sequenceNumber=\"XXX\"/", in); - } else { - return in; - } - } -} diff --git a/tests/src/java/org/apache/log4j/util/XMLTimestampFilter.java b/tests/src/java/org/apache/log4j/util/XMLTimestampFilter.java index 85b7b5fc84..dfac8c798c 100644 --- a/tests/src/java/org/apache/log4j/util/XMLTimestampFilter.java +++ b/tests/src/java/org/apache/log4j/util/XMLTimestampFilter.java @@ -19,17 +19,14 @@ import org.apache.oro.text.perl.Perl5Util; - public class XMLTimestampFilter implements Filter { + Perl5Util util = new Perl5Util(); - public String filter(String in) { - if(in == null) { - return null; - } - if (util.match("/timestamp=\"\\d{10,13}\"/", in)) { - return util.substitute( - "s/timestamp=\"\\d{10,13}\"/timestamp=\"XXX\"/", in); + public + String filter(String in) { + if(util.match("/timestamp=\"\\d{10,13}\"/", in)) { + return util.substitute("s/timestamp=\"\\d{10,13}\"/timestamp=\"XXX\"/", in); } else { return in; } diff --git a/tests/src/java/org/apache/log4j/varia/ERFATestCase.java b/tests/src/java/org/apache/log4j/varia/ERFATestCase.java index 291cf36f48..31b23ab249 100644 --- a/tests/src/java/org/apache/log4j/varia/ERFATestCase.java +++ b/tests/src/java/org/apache/log4j/varia/ERFATestCase.java @@ -52,7 +52,6 @@ public void tearDown() { /** * Test ExternallyRolledFileAppender constructor. - * @deprecated since class under test is deprecated. */ public void testConstructor() { ExternallyRolledFileAppender appender = @@ -66,7 +65,6 @@ public void testConstructor() { * @param msg message, may not be null. * @param expectedResponse expected response, may not be null. * @throws IOException thrown on IO error. - * @deprecated since class under test is deprecated. */ void sendMessage(int port, final String msg, final String expectedResponse) throws IOException { Socket socket = new Socket((String) null, port); @@ -83,7 +81,6 @@ void sendMessage(int port, final String msg, final String expectedResponse) thro /** * Test externally triggered rollover. * @throws IOException thrown on IO error. - * @deprecated since class under test is deprecated. */ public void testRollover() throws IOException { ExternallyRolledFileAppender erfa = @@ -104,6 +101,10 @@ public void testRollover() throws IOException { } catch(SecurityException ex) { return; } + try { + Thread.sleep(100); + } catch(InterruptedException ex) { + } root.addAppender(erfa); diff --git a/tests/src/java/org/apache/log4j/varia/ErrorHandlerTestCase.java b/tests/src/java/org/apache/log4j/varia/ErrorHandlerTestCase.java new file mode 100644 index 0000000000..b0001f8730 --- /dev/null +++ b/tests/src/java/org/apache/log4j/varia/ErrorHandlerTestCase.java @@ -0,0 +1,132 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.varia; + +import junit.framework.TestCase; +import org.apache.log4j.Appender; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.log4j.spi.ErrorHandler; +import org.apache.log4j.util.Filter; +import org.apache.log4j.util.Transformer; +import org.apache.log4j.util.Compare; +import org.apache.log4j.util.JunitTestRunnerFilter; +import org.apache.log4j.util.SunReflectFilter; +import org.apache.log4j.util.LineNumberFilter; +import org.apache.log4j.util.ControlFilter; +import org.apache.log4j.xml.DOMConfigurator; +import org.apache.log4j.PropertyConfigurator; + +public class ErrorHandlerTestCase extends TestCase { + + static String TEMP = "output/temp"; + static String FILTERED = "output/filtered"; + + + static String EXCEPTION1 = "java.lang.Exception: Just testing"; + static String EXCEPTION2 = "\\s*at .*\\(.*\\)"; + static String EXCEPTION3 = "\\s*at .*\\(Native Method\\)"; + + static String TEST1_PAT = + "FALLBACK - (root|test) - Message \\d"; + + + Logger root; + Logger logger; + + public ErrorHandlerTestCase(String name) { + super(name); + } + + public void setUp() { + root = Logger.getRootLogger(); + logger = Logger.getLogger("test"); + } + + public void tearDown() { + root.getLoggerRepository().resetConfiguration(); + } + + public void test1() throws Exception { + DOMConfigurator.configure("input/xml/fallback1.xml"); + Appender primary = root.getAppender("PRIMARY"); + ErrorHandler eh = primary.getErrorHandler(); + assertNotNull(eh); + + common(); + + ControlFilter cf = new ControlFilter(new String[]{TEST1_PAT, + EXCEPTION1, EXCEPTION2, EXCEPTION3}); + + Transformer.transform(TEMP, FILTERED, new Filter[] {cf, + new LineNumberFilter(), + new JunitTestRunnerFilter(), + new SunReflectFilter()}); + + + assertTrue(Compare.compare(FILTERED, "witness/fallback1")); + } + + public void test2() throws Exception { + PropertyConfigurator.configure("input/fallback1.properties"); + Appender primary = root.getAppender("PRIMARY"); + ErrorHandler eh = primary.getErrorHandler(); + assertNotNull(eh); + + common(); + + ControlFilter cf = new ControlFilter(new String[]{TEST1_PAT, + EXCEPTION1, EXCEPTION2, EXCEPTION3}); + + Transformer.transform(TEMP, FILTERED, new Filter[] {cf, + new LineNumberFilter(), + new JunitTestRunnerFilter(), + new SunReflectFilter()}); + + + assertTrue(Compare.compare(FILTERED, "witness/fallback1")); + } + + void common() { + int i = -1; + + logger.debug("Message " + ++i); + root.debug("Message " + i); + + logger.info ("Message " + ++i); + root.info("Message " + i); + + logger.warn ("Message " + ++i); + root.warn("Message " + i); + + logger.error("Message " + ++i); + root.error("Message " + i); + + logger.log(Level.FATAL, "Message " + ++i); + root.log(Level.FATAL, "Message " + i); + + Exception e = new Exception("Just testing"); + logger.debug("Message " + ++i, e); + root.debug("Message " + i, e); + + logger.error("Message " + ++i, e); + root.error("Message " + i, e); + + } + +} diff --git a/tests/src/java/org/apache/log4j/varia/LevelMatchFilterTestCase.java b/tests/src/java/org/apache/log4j/varia/LevelMatchFilterTestCase.java index e1f65ddd3d..1afc0d502c 100644 --- a/tests/src/java/org/apache/log4j/varia/LevelMatchFilterTestCase.java +++ b/tests/src/java/org/apache/log4j/varia/LevelMatchFilterTestCase.java @@ -17,33 +17,37 @@ package org.apache.log4j.varia; -import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import junit.framework.Test; +import org.apache.log4j.Logger; +import org.apache.log4j.Level; import org.apache.log4j.Appender; import org.apache.log4j.FileAppender; import org.apache.log4j.Layout; -import org.apache.log4j.Level; -import org.apache.log4j.Logger; import org.apache.log4j.SimpleLayout; -import org.apache.log4j.util.Compare; -import org.apache.log4j.filter.DenyAllFilter; -import org.apache.log4j.filter.LevelMatchFilter; +import org.apache.log4j.varia.LevelMatchFilter; +import org.apache.log4j.varia.DenyAllFilter; +import org.apache.log4j.util.Transformer; +import org.apache.log4j.util.Compare; +import org.apache.log4j.util.LineNumberFilter; /** - Test case for varia/LevelMatchFilter.java. Test both the accept - and deny cases. Testing the accept requires the use of the - DenyAllFilter to prevent non-matched messages from still getting - logged to the appender. + Test case for varia/LevelMatchFilter.java. */ public class LevelMatchFilterTestCase extends TestCase { - static String ACCEPT_FILE = "output/LevelMatchFilter_accept"; - static String ACCEPT_WITNESS = "witness/LevelMatchFilter_accept"; - static String DENY_FILE = "output/LevelMatchFilter_deny"; - static String DENY_WITNESS = "witness/LevelMatchFilter_deny"; - Logger root; + + static String ACCEPT_FILE = "output/LevelMatchFilter_accept"; + static String ACCEPT_FILTERED = "output/LevelMatchFilter_accept_filtered"; + static String ACCEPT_WITNESS = "witness/LevelMatchFilter_accept"; + + static String DENY_FILE = "output/LevelMatchFilter_deny"; + static String DENY_FILTERED = "output/LevelMatchFilter_deny_filtered"; + static String DENY_WITNESS = "witness/LevelMatchFilter_deny"; + + Logger root; Logger logger; public LevelMatchFilterTestCase(String name) { @@ -55,75 +59,77 @@ public void setUp() { root.removeAllAppenders(); } - public void tearDown() { + public void tearDown() { root.getLoggerRepository().resetConfiguration(); } public void accept() throws Exception { + // set up appender Layout layout = new SimpleLayout(); Appender appender = new FileAppender(layout, ACCEPT_FILE, false); - + // create LevelMatchFilter LevelMatchFilter matchFilter = new LevelMatchFilter(); - - // attach match filter to appender + + // attach match filter to appender appender.addFilter(matchFilter); - + // attach DenyAllFilter to end of filter chain to deny neutral // (non matching) messages appender.addFilter(new DenyAllFilter()); - + // set appender on root and set level to debug root.addAppender(appender); - root.setLevel(Level.DEBUG); - - Level[] levelArray = - new Level[] { Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR, Level.FATAL }; - + root.setLevel(Level.TRACE); + + Level[] levelArray = new Level[] {Level.TRACE, Level.DEBUG, Level.INFO, Level.WARN, + Level.ERROR, Level.FATAL}; for (int x = 0; x < levelArray.length; x++) { // set the level to match matchFilter.setLevelToMatch(levelArray[x].toString()); - common( - "pass " + x + "; filter set to accept only " - + levelArray[x].toString() + " msgs"); + common("pass " + x + "; filter set to accept only " + + levelArray[x].toString() + " msgs"); } - - assertTrue(Compare.compare(ACCEPT_FILE, ACCEPT_WITNESS)); + + Transformer.transform(ACCEPT_FILE, ACCEPT_FILTERED, new LineNumberFilter()); + assertTrue(Compare.compare(ACCEPT_FILTERED, ACCEPT_WITNESS)); } public void deny() throws Exception { + // set up appender Layout layout = new SimpleLayout(); Appender appender = new FileAppender(layout, DENY_FILE, false); - + // create LevelMatchFilter, set to deny matches LevelMatchFilter matchFilter = new LevelMatchFilter(); matchFilter.setAcceptOnMatch(false); - - // attach match filter to appender + + // attach match filter to appender appender.addFilter(matchFilter); - + // set appender on root and set level to debug root.addAppender(appender); - root.setLevel(Level.DEBUG); - - Level[] levelArray = - new Level[] { Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR, Level.FATAL }; - + root.setLevel(Level.TRACE); + + Level[] levelArray = new Level[] {Level.TRACE, Level.DEBUG, Level.INFO, Level.WARN, + Level.ERROR, Level.FATAL}; for (int x = 0; x < levelArray.length; x++) { // set the level to match matchFilter.setLevelToMatch(levelArray[x].toString()); - common( - "pass " + x + "; filter set to deny only " + levelArray[x].toString() - + " msgs"); + common("pass " + x + "; filter set to deny only " + levelArray[x].toString() + + " msgs"); } - - assertTrue(Compare.compare(DENY_FILE, DENY_WITNESS)); + + Transformer.transform(DENY_FILE, DENY_FILTERED, new LineNumberFilter()); + assertTrue(Compare.compare(DENY_FILTERED, DENY_WITNESS)); } + void common(String msg) { Logger logger = Logger.getLogger("test"); + logger.trace(msg); logger.debug(msg); logger.info(msg); logger.warn(msg); @@ -135,7 +141,7 @@ public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(new LevelMatchFilterTestCase("accept")); suite.addTest(new LevelMatchFilterTestCase("deny")); - return suite; } + } diff --git a/tests/src/java/org/apache/log4j/varia/LevelRangeFilterTestCase.java b/tests/src/java/org/apache/log4j/varia/LevelRangeFilterTestCase.java deleted file mode 100644 index ebaae4d736..0000000000 --- a/tests/src/java/org/apache/log4j/varia/LevelRangeFilterTestCase.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.varia; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.apache.log4j.Appender; -import org.apache.log4j.FileAppender; -import org.apache.log4j.Layout; -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.apache.log4j.SimpleLayout; -import org.apache.log4j.util.Compare; -import org.apache.log4j.filter.LevelRangeFilter; - - -/** - Test case for varia/LevelRangeFilter.java. - -

    Please note that in the witness file some passes are not - recorded. This is due to the max level being set to less - than the min level, thus no messages are logged on that pass. - This is correct behavior. - */ -public class LevelRangeFilterTestCase extends TestCase { - static String ACCEPT_FILE = "output/LevelRangeFilter_accept"; - static String ACCEPT_WITNESS = "witness/LevelRangeFilter_accept"; - static String NEUTRAL_FILE = "output/LevelRangeFilter_neutral"; - static String NEUTRAL_WITNESS = "witness/LevelRangeFilter_neutral"; - Logger root; - - public LevelRangeFilterTestCase(String name) { - super(name); - } - - public void setUp() { - root = Logger.getRootLogger(); - root.removeAllAppenders(); - } - - public void tearDown() { - root.getLoggerRepository().resetConfiguration(); - } - - public void accept() throws Exception { - // set up appender - Layout layout = new SimpleLayout(); - Appender appender = new FileAppender(layout, ACCEPT_FILE, false); - - // create LevelRangeFilter - LevelRangeFilter rangeFilter = new LevelRangeFilter(); - - // set it to accept on a match - rangeFilter.setAcceptOnMatch(true); - - // attach match filter to appender - appender.addFilter(rangeFilter); - - // set appender on root and set level to debug - root.addAppender(appender); - root.setLevel(Level.DEBUG); - - int passCount = 0; - - // test with no min or max set - common("pass " + passCount + "; no min or max set"); - passCount++; - - // test with a min set - rangeFilter.setLevelMin(Level.WARN); - common("pass " + passCount + "; min set to WARN, max not set"); - passCount++; - - // create a clean filter - appender.clearFilters(); - rangeFilter = new LevelRangeFilter(); - appender.addFilter(rangeFilter); - - //test with max set - rangeFilter.setLevelMax(Level.WARN); - common("pass " + passCount + "; min not set, max set to WARN"); - passCount++; - - Level[] levelArray = - new Level[] { Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR, Level.FATAL }; - - for (int x = 0; x < levelArray.length; x++) { - // set the min level to match - rangeFilter.setLevelMin(levelArray[x]); - - for (int y = levelArray.length - 1; y >= 0; y--) { - // set max level to match - rangeFilter.setLevelMax(levelArray[y]); - - common( - "pass " + passCount + "; filter set to accept between " - + levelArray[x].toString() + " and " + levelArray[y].toString() - + " msgs"); - - // increment passCount - passCount++; - } - } - - assertTrue(Compare.compare(ACCEPT_FILE, ACCEPT_WITNESS)); - } - - public void neutral() throws Exception { - // set up appender - Layout layout = new SimpleLayout(); - Appender appender = new FileAppender(layout, NEUTRAL_FILE, false); - - // create LevelRangeFilter - LevelRangeFilter rangeFilter = new LevelRangeFilter(); - - // set it to not accept on a match - rangeFilter.setAcceptOnMatch(false); - - // attach match filter to appender - appender.addFilter(rangeFilter); - - // set appender on root and set level to debug - root.addAppender(appender); - root.setLevel(Level.DEBUG); - - int passCount = 0; - - // test with no min or max set - common("pass " + passCount + "; no min or max set"); - passCount++; - - // test with a min set - rangeFilter.setLevelMin(Level.WARN); - common("pass " + passCount + "; min set to WARN, max not set"); - passCount++; - - // create a clean filter - appender.clearFilters(); - rangeFilter = new LevelRangeFilter(); - appender.addFilter(rangeFilter); - - //test with max set - rangeFilter.setLevelMax(Level.WARN); - common("pass " + passCount + "; min not set, max set to WARN"); - passCount++; - - Level[] levelArray = - new Level[] { Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR, Level.FATAL }; - - for (int x = 0; x < levelArray.length; x++) { - // set the min level to match - rangeFilter.setLevelMin(levelArray[x]); - - for (int y = levelArray.length - 1; y >= 0; y--) { - // set max level to match - rangeFilter.setLevelMax(levelArray[y]); - - common( - "pass " + passCount + "; filter set to accept between " - + levelArray[x].toString() + " and " + levelArray[y].toString() - + " msgs"); - - // increment passCount - passCount++; - } - } - - assertTrue(Compare.compare(NEUTRAL_FILE, NEUTRAL_WITNESS)); - } - - void common(String msg) { - Logger logger = Logger.getLogger("test"); - logger.debug(msg); - logger.info(msg); - logger.warn(msg); - logger.error(msg); - logger.fatal(msg); - } - - public static Test suite() { - TestSuite suite = new TestSuite(); - suite.addTest(new LevelRangeFilterTestCase("accept")); - suite.addTest(new LevelRangeFilterTestCase("neutral")); - - return suite; - } -} diff --git a/tests/src/java/org/apache/log4j/watchdog/FileWatchdogTestCase.java b/tests/src/java/org/apache/log4j/watchdog/FileWatchdogTestCase.java deleted file mode 100644 index bc63019908..0000000000 --- a/tests/src/java/org/apache/log4j/watchdog/FileWatchdogTestCase.java +++ /dev/null @@ -1,577 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.watchdog; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; - -import junit.framework.TestCase; - -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.PropertyConfigurator; -import org.apache.log4j.util.Compare; -import org.apache.log4j.spi.LoggerRepositoryEx; -import org.apache.log4j.joran.JoranConfigurator; -import org.apache.log4j.Level; -import org.apache.log4j.xml.DOMConfigurator; - -public class FileWatchdogTestCase extends TestCase { - - private Logger testLogger = Logger.getLogger(FileWatchdogTestCase.class); - private Logger logger = Logger.getLogger("test.FileWatchdogTestCase"); - - static String SOURCE_CONFIG = "input/watchdog/watchdog.FileWatchdog"; - static String FILE = "output/watchdog.FileWatchdog"; - static String WITNESS = "witness/watchdog/watchdog.FileWatchdog"; - - public FileWatchdogTestCase(String name) { - super(name); - } - - protected void setUp() throws Exception { - LogManager.getLoggerRepository().resetConfiguration(); - logger.setLevel(Level.DEBUG); - Thread.sleep(100); - } - - private void copyFile(File src, File dst) throws Exception { - if (dst.exists()) { - for (int x = 0; x < 5; x++) { - if (x == 4) { - assertTrue("File " + dst.getAbsolutePath() + - " not deleted", false); - } - if (dst.delete()) break; - Thread.sleep(750); - } - } - - FileOutputStream out = new FileOutputStream(dst); - FileInputStream in = new FileInputStream(src); - byte[] buffer = new byte[1024]; - int size; - do { - size = in.read(buffer); - if (size > 0) out.write(buffer,0,size); - } while (size > 0); - - try { - in.close(); - } catch (Exception e) { - // don't care - } - - try { - out.close(); - } catch (Exception e) { - // don't care - } - } - - private String getSourceXMLConfigFile(String caseName, int index) { - - return SOURCE_CONFIG + "." + caseName + "_" + index + ".xml"; - } - - private String getXMLConfigFile(String caseName) { - - return FILE + "." + caseName + ".xml"; - } - - private String getSourceConfigFile(String caseName, int index) { - - return SOURCE_CONFIG + "." + caseName + "_" + index + ".properties"; - } - - private String getConfigFile(String caseName) { - - return FILE + "." + caseName + ".properties"; - } - - private String getOutputFile(String caseName) { - - return FILE + "." + caseName + ".txt"; - } - - private String getWitnessFile(String caseName) { - - return WITNESS + "." + caseName + ".txt"; - } - - // basic test of plugin in standalone mode - public void testJoranConfigurator() throws Exception { - - File outFile = new File(getOutputFile("test1")); - if (outFile.exists()) { - assertTrue(outFile.delete()); - } - - // set up the needed file references - File sourceFile1 = new File(getSourceXMLConfigFile("test1", 1)); - File sourceFile2 = new File(getSourceXMLConfigFile("test1", 2)); - assertTrue(sourceFile1.exists()); - assertTrue(sourceFile2.exists()); - - File configFile = new File(getXMLConfigFile("test1")); - - // move the first config file into place - copyFile(sourceFile1, configFile); - assertTrue(configFile.exists()); - - testLogger.debug("first config file in place: " + configFile.getAbsolutePath()); - - // configure environment to first config file - JoranConfigurator configurator = new JoranConfigurator(); - configurator.doConfigure(configFile.getAbsolutePath(), - LogManager.getLoggerRepository()); - - testLogger.debug("log4j configured with configFile"); - - // now watch the file for changes - FileWatchdog watchdog = new FileWatchdog(); - watchdog.setName("test1"); - watchdog.setFile(configFile.getAbsolutePath()); - watchdog.setInterval(1000); - watchdog.setConfigurator(JoranConfigurator.class.getName()); - ((LoggerRepositoryEx) LogManager.getLoggerRepository()).getPluginRegistry().addPlugin(watchdog); - watchdog.activateOptions(); - - testLogger.debug("watchdog activated"); - - // output some test messages - logger.debug("debug message"); - logger.info("info message"); - logger.warn("warn message"); - logger.error("error message"); - logger.fatal("fatal message"); - - testLogger.debug("first set of test messages output"); - - Thread.sleep(2000); - - testLogger.debug("about to copy second config file"); - - // copy over a new version of the config file - copyFile(sourceFile2, configFile); - - testLogger.debug("second config file copied"); - - // wait a few seconds for the watchdog to react - for (int i = 0; i < 40; i++) { - testLogger.debug("sleeping for 500 ms"); - Thread.sleep(500); - testLogger.debug("level for logger " + logger.getName() + " is " + logger.getLevel()); - if (logger.getLevel() == Level.INFO) { - // output some test messages - logger.debug("debug message"); - logger.info("info message"); - logger.warn("warn message"); - logger.error("error message"); - logger.fatal("fatal message"); - - testLogger.debug("second set of test messages output"); - - assertTrue(Compare.compare(getOutputFile("test1"), - getWitnessFile("test1"))); - return; - } - testLogger.debug("looping for level check"); - } - fail("Expected change in level did not occur within 20 seconds."); - } - - // basic test of plugin in standalone mode with PropertyConfigurator - public void testPropertyConfigurator() throws Exception { - File outFile = new File(getOutputFile("test2")); - delete(outFile); - - // set up the needed file references - File sourceFile1 = new File(getSourceConfigFile("test2", 1)); - File sourceFile2 = new File(getSourceConfigFile("test2", 2)); - assertTrue(sourceFile1.exists()); - assertTrue(sourceFile2.exists()); - - File configFile = new File(getConfigFile("test2")); - - // move the first config file into place - copyFile(sourceFile1, configFile); - assertTrue(configFile.exists()); - - testLogger.debug("first config file in place: " + configFile.getAbsolutePath()); - - // configure environment to first config file - PropertyConfigurator configurator = new PropertyConfigurator(); - configurator.doConfigure(configFile.getAbsolutePath(), - LogManager.getLoggerRepository()); - - testLogger.debug("log4j configured with configFile"); - - // now watch the file for changes - FileWatchdog watchdog = new FileWatchdog(); - watchdog.setName("test2"); - watchdog.setFile(configFile.getAbsolutePath()); - watchdog.setInterval(1000); - watchdog.setConfigurator(PropertyConfigurator.class.getName()); - ((LoggerRepositoryEx) LogManager.getLoggerRepository()).getPluginRegistry().addPlugin(watchdog); - watchdog.activateOptions(); - - testLogger.debug("watchdog activated"); - - // output some test messages - logger.debug("debug message"); - logger.info("info message"); - logger.warn("warn message"); - logger.error("error message"); - logger.fatal("fatal message"); - - testLogger.debug("first set of test messages output"); - - Thread.sleep(2000); - - testLogger.debug("about to copy second config file"); - - // copy over a new version of the config file - copyFile(sourceFile2, configFile); - - testLogger.debug("second config file copied"); - - // wait a few seconds for the watchdog to react - for (int i = 0; i < 40; i++) { - testLogger.debug("sleeping for 500 ms"); - Thread.sleep(500); - testLogger.debug("level for logger " + logger.getName() + " is " + logger.getLevel()); - if (logger.getLevel() == Level.INFO) { - // output some test messages - logger.debug("debug message"); - logger.info("info message"); - logger.warn("warn message"); - logger.error("error message"); - logger.fatal("fatal message"); - - testLogger.debug("second set of test messages output"); - Thread.sleep(500); - - assertTrue("output does not match", Compare.compare(getOutputFile("test2"), - getWitnessFile("test2"))); - return; - } - testLogger.debug("looping for level check"); - } - fail("Expected change in level did not occur within 20 seconds."); - } - - public void testJoranConfigurationError() throws Exception { - File outFile = new File(getOutputFile("test3")); - delete(outFile); - - // set up the needed file references - File sourceFile1 = new File(getSourceXMLConfigFile("test3", 1)); - File sourceFile2 = new File(getSourceXMLConfigFile("test1", 2)); - assertTrue(sourceFile1.exists()); - assertTrue(sourceFile2.exists()); - - // config file should not exist yet - File configFile = new File(getXMLConfigFile("test3")); - delete(configFile); - - // now watch the nonexistent file for changes - FileWatchdog watchdog = new FileWatchdog(); - watchdog.setName("test3"); - watchdog.setFile(configFile.getAbsolutePath()); - watchdog.setInterval(1000); - watchdog.setConfigurator(JoranConfigurator.class.getName()); - ((LoggerRepositoryEx) LogManager.getLoggerRepository()).getPluginRegistry().addPlugin(watchdog); - watchdog.activateOptions(); - - testLogger.debug("watchdog activated"); - - // the file does not exist, so the modification time should never change - long modTime = watchdog.getLastModTime(); - for (int count = 0; count < 5; count++) { - if (modTime != watchdog.getLastModTime()) { - assertTrue("watchdog mod time changed when no file", false); - } - Thread.sleep(500); - } - - testLogger.debug("no file, mod time not changed: " + modTime); - - // move the bad config file into place - copyFile(sourceFile1, configFile); - assertTrue(configFile.exists()); - - testLogger.debug("bad config file put into place"); - - // the file is "bad", so the modification time should never change - for (int count = 0; count < 7; count++) { - if (modTime != watchdog.getLastModTime()) { - assertTrue("watchdog mod time changed for bad file", false); - } - Thread.sleep(500); - } - - testLogger.debug("bad file, mod time not changed: " + modTime); - - // move the good config file into place - copyFile(sourceFile2, configFile); - assertTrue(configFile.exists()); - - testLogger.debug("moved good config file into place"); - - // the file is good, so the modification time and level should change - for (int count = 0; count < 7; count++) { - if (modTime != watchdog.getLastModTime()) { - assertTrue(logger.getLevel() == Level.INFO); - break; - } - - if (count == 6) { - assertTrue("mod time for good file never changed", false); - } - - Thread.sleep(500); - } - - testLogger.debug("good file, modTime changed: " + modTime); - } - - private void delete(File f) { - if (f.exists()) { - assertTrue(f.delete()); - } - } - - public void testPropertyConfigurationError() throws Exception { - File outFile = new File(getOutputFile("test4")); - delete(outFile); - - // set up the needed file references - // need a "bad" property file - //File sourceFile1 = new File(getSourceConfigFile("test4", 1)); - File sourceFile2 = new File(getSourceConfigFile("test2", 2)); - //assertTrue(sourceFile1.exists()); - assertTrue(sourceFile2.exists()); - - File configFile = new File(getConfigFile("test4")); - delete(configFile); - // assertFalse(configFile.exists()); - - // now watch the nonexistent file for changes - FileWatchdog watchdog = new FileWatchdog(); - watchdog.setName("test4"); - watchdog.setFile(configFile.getAbsolutePath()); - watchdog.setInterval(1000); - watchdog.setConfigurator(PropertyConfigurator.class.getName()); - ((LoggerRepositoryEx) LogManager.getLoggerRepository()).getPluginRegistry().addPlugin(watchdog); - watchdog.activateOptions(); - - testLogger.debug("watchdog activated"); - - // the file does not exist, so the modification time should never change - long modTime = watchdog.getLastModTime(); - for (int count = 0; count < 5; count++) { - if (modTime != watchdog.getLastModTime()) { - assertTrue("watchdog mod time changed when no file", false); - } - Thread.sleep(500); - } - - testLogger.debug("no file, mod time not changed: " + modTime); - -/* need a "bad" property file - // move the bad config file into place - copyFile(sourceFile1, configFile); - assertTrue(configFile.exists()); - - testLogger.debug("bad config file put into place"); - - // the file is "bad", so the modification time should never change - for (int count = 0; count < 7; count++) { - if (modTime != watchdog.getLastModTime()) { - assertTrue("watchdog mod time changed for bad file", false); - } - Thread.sleep(500); - } - - testLogger.debug("bad file, mod time not changed: " + modTime); -*/ - - // move the good config file into place - copyFile(sourceFile2, configFile); - assertTrue(configFile.exists()); - - testLogger.debug("moved good config file into place"); - - // the file is good, so the modification time and level should change - for (int count = 0; count < 7; count++) { - if (modTime != watchdog.getLastModTime()) { - assertTrue(logger.getLevel() == Level.INFO); - break; - } - - if (count == 6) { - assertTrue("mod time for good file never changed", false); - } - - Thread.sleep(500); - } - - testLogger.debug("good file, modTime changed: " + modTime); - } - - public void testDOMConfigureAndWatch() throws Exception { - File outFile = new File(getOutputFile("test5")); - if (outFile.exists()) { - assertTrue(outFile.delete()); - } - - // set up the needed file references - File sourceFile1 = new File(getSourceXMLConfigFile("test5", 1)); - File sourceFile2 = new File(getSourceXMLConfigFile("test5", 2)); - assertTrue(sourceFile1.exists()); - assertTrue(sourceFile2.exists()); - - File configFile = new File(getXMLConfigFile("test5")); - - // move the first config file into place - copyFile(sourceFile1, configFile); - assertTrue(configFile.exists()); - - testLogger.debug("first config file in place: " + configFile.getAbsolutePath()); - - // now watch the file for changes - DOMConfigurator.configureAndWatch(configFile.getAbsolutePath(), 1000); - - testLogger.debug("configureAndWatch activated"); - - // output some test messages - logger.debug("debug message"); - logger.info("info message"); - logger.warn("warn message"); - logger.error("error message"); - logger.fatal("fatal message"); - - testLogger.debug("first set of test messages output"); - - Thread.sleep(2000); - - testLogger.debug("about to copy second config file"); - - // copy over a new version of the config file - copyFile(sourceFile2, configFile); - - testLogger.debug("second config file copied"); - - // wait a few seconds for the watchdog to react - for (int i = 0; i < 40; i++) { - testLogger.debug("sleeping for 500 ms"); - Thread.sleep(500); - testLogger.debug("level for logger " + logger.getName() + " is " + logger.getLevel()); - if (logger.getLevel() == Level.INFO) { - // output some test messages - logger.debug("debug message"); - logger.info("info message"); - logger.warn("warn message"); - logger.error("error message"); - logger.fatal("fatal message"); - - testLogger.debug("second set of test messages output"); - Thread.sleep(500); - - assertTrue("output does not match", Compare.compare(getOutputFile("test5"), - getWitnessFile("test5"))); - return; - } - testLogger.debug("looping for level check"); - } - fail("Expected change in level did not occur within 20 seconds."); - } - - /* there is a bug in property configurator where it will not work a second - time, so commenting this out for now - public void testPropertyConfigureAndWatch() throws Exception { - File outFile = new File(getOutputFile("test6")); - if (outFile.exists()) { - assertTrue(outFile.delete()); - } - - // set up the needed file references - File sourceFile1 = new File(getSourceConfigFile("test6", 1)); - File sourceFile2 = new File(getSourceConfigFile("test6", 2)); - assertTrue(sourceFile1.exists()); - assertTrue(sourceFile2.exists()); - - File configFile = new File(getConfigFile("test6")); - - // move the first config file into place - copyFile(sourceFile1, configFile); - assertTrue(configFile.exists()); - - testLogger.debug("first config file in place: " + configFile.getAbsolutePath()); - - // now watch the file for changes - PropertyConfigurator.configureAndWatch(configFile.getAbsolutePath(), 1000); - - testLogger.debug("configureAndWatch activated"); - - // output some test messages - logger.debug("debug message"); - logger.info("info message"); - logger.warn("warn message"); - logger.error("error message"); - logger.fatal("fatal message"); - - testLogger.debug("first set of test messages output"); - - Thread.sleep(2000); - - testLogger.debug("about to copy second config file"); - - // copy over a new version of the config file - copyFile(sourceFile2, configFile); - - testLogger.debug("second config file copied"); - - // wait a few seconds for the watchdog to react - for (int i = 0; i < 40; i++) { - testLogger.debug("sleeping for 500 ms"); - Thread.sleep(500); - testLogger.debug("level for logger " + logger.getName() + " is " + logger.getLevel()); - if (logger.getLevel() == Level.INFO) { - // output some test messages - logger.debug("debug message"); - logger.info("info message"); - logger.warn("warn message"); - logger.error("error message"); - logger.fatal("fatal message"); - - testLogger.debug("second set of test messages output"); - Thread.sleep(1000); - - assertTrue("output does not match", Compare.compare(getOutputFile("test6"), - getWitnessFile("test6"))); - return; - } - testLogger.debug("looping for level check"); - } - fail("Expected change in level did not occur within 20 seconds."); - } - */ -} diff --git a/tests/src/java/org/apache/log4j/xml/CustomLevelTestCase.java b/tests/src/java/org/apache/log4j/xml/CustomLevelTestCase.java index cd455158ec..52c366ae94 100644 --- a/tests/src/java/org/apache/log4j/xml/CustomLevelTestCase.java +++ b/tests/src/java/org/apache/log4j/xml/CustomLevelTestCase.java @@ -20,15 +20,14 @@ import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; - -import org.apache.log4j.*; -import org.apache.log4j.joran.JoranConfigurator; +import org.apache.log4j.Logger; import org.apache.log4j.util.Compare; - public class CustomLevelTestCase extends TestCase { + static String TEMP = "output/temp"; - Logger root; + + Logger root; Logger logger; public CustomLevelTestCase(String name) { @@ -40,71 +39,51 @@ public void setUp() { logger = Logger.getLogger(CustomLevelTestCase.class); } - public void tearDown() { + public void tearDown() { root.getLoggerRepository().resetConfiguration(); - - Logger logger = LogManager.getLoggerRepository().getLogger("LOG4J"); - logger.setAdditivity(false); - logger.addAppender( - new ConsoleAppender(new PatternLayout("log4j: %-22c{2} - %m%n"))); } public void test1() throws Exception { - org.apache.log4j.BasicConfigurator.configure(); - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure("input/xml/customLevel1.xml", LogManager.getLoggerRepository()); - jc.dumpErrors(); - + DOMConfigurator.configure("input/xml/customLevel1.xml"); common(); - assertTrue(Compare.compare(TEMP, "witness/xml/customLevel.1")); + assertTrue(Compare.compare(TEMP, "witness/customLevel.1")); } public void test2() throws Exception { - org.apache.log4j.BasicConfigurator.configure(); - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure("input/xml/customLevel2.xml", LogManager.getLoggerRepository()); - jc.dumpErrors(); - + DOMConfigurator.configure("input/xml/customLevel2.xml"); common(); - assertTrue(Compare.compare(TEMP, "witness/xml/customLevel.2")); + assertTrue(Compare.compare(TEMP, "witness/customLevel.2")); } public void test3() throws Exception { - org.apache.log4j.BasicConfigurator.configure(); - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure("input/xml/customLevel3.xml", LogManager.getLoggerRepository()); - jc.dumpErrors(); - + DOMConfigurator.configure("input/xml/customLevel3.xml"); common(); - assertTrue(Compare.compare(TEMP, "witness/xml/customLevel.3")); + assertTrue(Compare.compare(TEMP, "witness/customLevel.3")); } public void test4() throws Exception { - org.apache.log4j.BasicConfigurator.configure(); - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure("input/xml/customLevel4.xml", LogManager.getLoggerRepository()); - jc.dumpErrors(); - + DOMConfigurator.configure("input/xml/customLevel4.xml"); common(); - assertTrue(Compare.compare(TEMP, "witness/xml/customLevel.4")); + assertTrue(Compare.compare(TEMP, "witness/customLevel.4")); } + void common() { int i = 0; logger.debug("Message " + ++i); - logger.info("Message " + ++i); - logger.warn("Message " + ++i); + logger.info ("Message " + ++i); + logger.warn ("Message " + ++i); logger.error("Message " + ++i); logger.log(XLevel.TRACE, "Message " + ++i); } - + public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(new CustomLevelTestCase("test1")); suite.addTest(new CustomLevelTestCase("test2")); suite.addTest(new CustomLevelTestCase("test3")); suite.addTest(new CustomLevelTestCase("test4")); - return suite; } + } diff --git a/tests/src/java/org/apache/log4j/xml/DOMTest.java b/tests/src/java/org/apache/log4j/xml/DOMTest.java deleted file mode 100644 index 508c522a2a..0000000000 --- a/tests/src/java/org/apache/log4j/xml/DOMTest.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.log4j.xml; - -import junit.framework.TestCase; - -import org.apache.log4j.Level; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.joran.JoranConfigurator; -import org.apache.log4j.spi.ErrorItem; -import org.apache.log4j.util.*; - -import java.io.File; - -import java.util.List; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - - -public class DOMTest extends TestCase { - static String TEMP_A1 = "output/temp.A1"; - static String TEMP_A2 = "output/temp.A2"; - static String FILTERED_A1 = "output/filtered.A1"; - static String FILTERED_A2 = "output/filtered.A2"; - static String EXCEPTION1 = "java.lang.Exception: Just testing"; - static String EXCEPTION2 = "\\s*at .*\\(.*:\\d{1,4}\\)"; - static String EXCEPTION3 = "\\s*at .*\\(Native Method\\)"; - static String TEST1_1A_PAT = - "(DEBUG|INFO |WARN |ERROR|FATAL) \\w*\\.\\w* - Message \\d"; - static String TEST1_1B_PAT = - "(DEBUG|INFO |WARN |ERROR|FATAL) root - Message \\d"; - static String TEST1_2_PAT = - "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3} " - + "\\[main]\\ (DEBUG|INFO|WARN|ERROR|FATAL) .* - Message \\d"; - Logger root; - Logger logger; - - public DOMTest(String name) { - super(name); - } - - public void setUp() { - root = Logger.getRootLogger(); - logger = Logger.getLogger(DOMTest.class); - } - - public void tearDown() { - root.getLoggerRepository().resetConfiguration(); - } - - public void test1() throws Exception { - //org.apache.log4j.BasicConfigurator.configure(); - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure("input/xml/DOMTest1.xml", LogManager.getLoggerRepository()); - dumpErrors(jc.getErrorList()); - common(); - - ControlFilter cf1 = - new ControlFilter( - new String[] { - TEST1_1A_PAT, TEST1_1B_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3 - }); - - ControlFilter cf2 = - new ControlFilter( - new String[] { TEST1_2_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); - - Transformer.transform( - TEMP_A1, FILTERED_A1, - new Filter[] { - cf1, new LineNumberFilter(), new SunReflectFilter(), - new JunitTestRunnerFilter() - }); - - Transformer.transform( - TEMP_A2, FILTERED_A2, - new Filter[] { - cf2, new LineNumberFilter(), new ISO8601Filter(), - new SunReflectFilter(), new JunitTestRunnerFilter() - }); - - assertTrue(Compare.compare(FILTERED_A1, "witness/xml/dom.A1.1")); - assertTrue(Compare.compare(FILTERED_A2, "witness/xml/dom.A2.1")); - } - - /** - * Identical test except that backslashes are used instead of - * forward slashes on all file specifications. Test is - * only applicable to Windows. - * - * @throws Exception Any exception will cause test to fail - */ - public void test2() throws Exception { - if (File.separatorChar == '\\') { - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure( - "input\\xml\\DOMTest2.xml", LogManager.getLoggerRepository()); - dumpErrors(jc.getErrorList()); - common(); - - ControlFilter cf1 = - new ControlFilter( - new String[] { - TEST1_1A_PAT, TEST1_1B_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3 - }); - - ControlFilter cf2 = - new ControlFilter( - new String[] { TEST1_2_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); - - Transformer.transform( - TEMP_A1 + ".2", FILTERED_A1 + ".2", - new Filter[] { - cf1, new LineNumberFilter(), new SunReflectFilter(), - new JunitTestRunnerFilter() - }); - - Transformer.transform( - TEMP_A2 + ".2", FILTERED_A2 + ".2", - new Filter[] { - cf2, new LineNumberFilter(), new ISO8601Filter(), - new SunReflectFilter(), new JunitTestRunnerFilter() - }); - - assertTrue(Compare.compare(FILTERED_A1 + ".2", "witness/xml/dom.A1.2")); - assertTrue(Compare.compare(FILTERED_A2 + ".2", "witness/xml/dom.A2.2")); - } - } - - /** - * This test checks the implementation of DOMConfigurator.doConfigure(Element) - * which is provided for compatibility with log4j 1.2 and used by excalibur-logging. - * - * @deprecated This test checks a deprecated method and so needs to be deprecated itself. - * - * @throws Exception on failure to find parser, etc. - */ - public void test3() throws Exception { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - factory.setValidating(false); - - DocumentBuilder builder = factory.newDocumentBuilder(); - org.w3c.dom.Document doc = - builder.parse(new File("input/xml/DOMTest3.xml")); - - DOMConfigurator domConfig = new DOMConfigurator(); - domConfig.doConfigure( - doc.getDocumentElement(), LogManager.getLoggerRepository()); - - dumpErrors(domConfig.getErrorList()); - common(); - - ControlFilter cf1 = - new ControlFilter( - new String[] { - TEST1_1A_PAT, TEST1_1B_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3 - }); - - ControlFilter cf2 = - new ControlFilter( - new String[] { TEST1_2_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); - - Transformer.transform( - TEMP_A1 + ".3", FILTERED_A1 + ".3", - new Filter[] { - cf1, new LineNumberFilter(), new SunReflectFilter(), - new JunitTestRunnerFilter() - }); - - Transformer.transform( - TEMP_A2 + ".3", FILTERED_A2 + ".3", - new Filter[] { - cf2, new LineNumberFilter(), new ISO8601Filter(), - new SunReflectFilter(), new JunitTestRunnerFilter() - }); - - assertTrue(Compare.compare(FILTERED_A1 + ".3", "witness/xml/dom.A1.3")); - assertTrue(Compare.compare(FILTERED_A2 + ".3", "witness/xml/dom.A2.3")); - } - - /** - * Tests processing of external entities in XML file. - */ - public void test4() throws Exception { - //org.apache.log4j.BasicConfigurator.configure(); - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure("input/xml/DOMTest4.xml", LogManager.getLoggerRepository()); - dumpErrors(jc.getErrorList()); - common(); - - ControlFilter cf1 = - new ControlFilter( - new String[] { - TEST1_1A_PAT, TEST1_1B_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3 - }); - - ControlFilter cf2 = - new ControlFilter( - new String[] { TEST1_2_PAT, EXCEPTION1, EXCEPTION2, EXCEPTION3 }); - - Transformer.transform( - TEMP_A1 + ".4", FILTERED_A1 + ".4", - new Filter[] { - cf1, new LineNumberFilter(), new SunReflectFilter(), - new JunitTestRunnerFilter() - }); - - Transformer.transform( - TEMP_A2 + ".4", FILTERED_A2 + ".4", - new Filter[] { - cf2, new LineNumberFilter(), new ISO8601Filter(), - new SunReflectFilter(), new JunitTestRunnerFilter() - }); - - assertTrue(Compare.compare(FILTERED_A1 + ".4", "witness/xml/dom.A1.4")); - assertTrue(Compare.compare(FILTERED_A2 + ".4", "witness/xml/dom.A2.4")); - } - - - void common() { - int i = -1; - - logger.debug("Message " + ++i); - root.debug("Message " + i); - - logger.info("Message " + ++i); - root.info("Message " + i); - - logger.warn("Message " + ++i); - root.warn("Message " + i); - - logger.error("Message " + ++i); - root.error("Message " + i); - - logger.log(Level.FATAL, "Message " + ++i); - root.log(Level.FATAL, "Message " + i); - - Exception e = new Exception("Just testing"); - logger.debug("Message " + ++i, e); - root.debug("Message " + i, e); - - logger.error("Message " + ++i, e); - root.error("Message " + i, e); - } - - void dumpErrors(List errorList) { - for (int i = 0; i < errorList.size(); i++) { - ErrorItem ei = (ErrorItem) errorList.get(i); - System.out.println(ei); - - Throwable t = ei.getException(); - - if (t != null) { - t.printStackTrace(System.out); - } - } - } -} diff --git a/tests/src/java/org/apache/log4j/xml/DOMTestCase.java b/tests/src/java/org/apache/log4j/xml/DOMTestCase.java new file mode 100644 index 0000000000..e664c43996 --- /dev/null +++ b/tests/src/java/org/apache/log4j/xml/DOMTestCase.java @@ -0,0 +1,419 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.xml; + +import junit.framework.TestCase; +import org.apache.log4j.Appender; +import org.apache.log4j.FileAppender; +import org.apache.log4j.Level; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.apache.log4j.VectorAppender; +import org.apache.log4j.spi.ErrorHandler; +import org.apache.log4j.spi.LoggerFactory; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.spi.ThrowableRenderer; +import org.apache.log4j.spi.OptionHandler; +import org.apache.log4j.spi.ThrowableRendererSupport; +import org.apache.log4j.util.Compare; +import org.apache.log4j.util.ControlFilter; +import org.apache.log4j.util.Filter; +import org.apache.log4j.util.ISO8601Filter; +import org.apache.log4j.util.JunitTestRunnerFilter; +import org.apache.log4j.util.LineNumberFilter; +import org.apache.log4j.util.SunReflectFilter; +import org.apache.log4j.util.Transformer; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +public class DOMTestCase extends TestCase { + + static String TEMP_A1 = "output/temp.A1"; + static String TEMP_A2 = "output/temp.A2"; + static String FILTERED_A1 = "output/filtered.A1"; + static String FILTERED_A2 = "output/filtered.A2"; + + + static String EXCEPTION1 = "java.lang.Exception: Just testing"; + static String EXCEPTION2 = "\\s*at .*\\(.*\\)"; + static String EXCEPTION3 = "\\s*at .*\\(Native Method\\)"; + static String EXCEPTION4 = "\\s*at .*\\(.*Compiled Code\\)"; + static String EXCEPTION5 = "\\s*at .*\\(.*libgcj.*\\)"; + + + static String TEST1_1A_PAT = + "(TRACE|DEBUG|INFO |WARN |ERROR|FATAL) \\w*\\.\\w* - Message \\d"; + + static String TEST1_1B_PAT = "(TRACE|DEBUG|INFO |WARN |ERROR|FATAL) root - Message \\d"; + + static String TEST1_2_PAT = "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3} "+ + "\\[main]\\ (TRACE|DEBUG|INFO|WARN|ERROR|FATAL) .* - Message \\d"; + + + + Logger root; + Logger logger; + + public DOMTestCase(String name) { + super(name); + } + + public void setUp() { + root = Logger.getRootLogger(); + logger = Logger.getLogger(DOMTestCase.class); + } + + public void tearDown() { + root.getLoggerRepository().resetConfiguration(); + } + + public void test1() throws Exception { + DOMConfigurator.configure("input/xml/DOMTestCase1.xml"); + common(); + + ControlFilter cf1 = new ControlFilter(new String[]{TEST1_1A_PAT, TEST1_1B_PAT, + EXCEPTION1, EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); + + ControlFilter cf2 = new ControlFilter(new String[]{TEST1_2_PAT, + EXCEPTION1, EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); + + Transformer.transform( + TEMP_A1, FILTERED_A1, + new Filter[] { + cf1, new LineNumberFilter(), new SunReflectFilter(), + new JunitTestRunnerFilter() + }); + + Transformer.transform( + TEMP_A2, FILTERED_A2, + new Filter[] { + cf2, new LineNumberFilter(), new ISO8601Filter(), + new SunReflectFilter(), new JunitTestRunnerFilter() + }); + + assertTrue(Compare.compare(FILTERED_A1, "witness/dom.A1.1")); + assertTrue(Compare.compare(FILTERED_A2, "witness/dom.A2.1")); + } + + /** + * Tests processing of external entities in XML file. + */ + public void test4() throws Exception { + DOMConfigurator.configure("input/xml/DOMTest4.xml"); + common(); + + ControlFilter cf1 = new ControlFilter(new String[]{TEST1_1A_PAT, TEST1_1B_PAT, + EXCEPTION1, EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); + + ControlFilter cf2 = new ControlFilter(new String[]{TEST1_2_PAT, + EXCEPTION1, EXCEPTION2, EXCEPTION3, EXCEPTION4, EXCEPTION5}); + + Transformer.transform( + TEMP_A1 + ".4", FILTERED_A1 + ".4", + new Filter[] { + cf1, new LineNumberFilter(), new SunReflectFilter(), + new JunitTestRunnerFilter() + }); + + Transformer.transform( + TEMP_A2 + ".4", FILTERED_A2 + ".4", + new Filter[] { + cf2, new LineNumberFilter(), new ISO8601Filter(), + new SunReflectFilter(), new JunitTestRunnerFilter() + }); + + assertTrue(Compare.compare(FILTERED_A1 + ".4", "witness/dom.A1.4")); + assertTrue(Compare.compare(FILTERED_A2 + ".4", "witness/dom.A2.4")); + } + + void common() { + String oldThreadName = Thread.currentThread().getName(); + Thread.currentThread().setName("main"); + + int i = -1; + + logger.trace("Message " + ++i); + root.trace("Message " + i); + + logger.debug("Message " + ++i); + root.debug("Message " + i); + + logger.info ("Message " + ++i); + root.info("Message " + i); + + logger.warn ("Message " + ++i); + root.warn("Message " + i); + + logger.error("Message " + ++i); + root.error("Message " + i); + + logger.log(Level.FATAL, "Message " + ++i); + root.log(Level.FATAL, "Message " + i); + + Exception e = new Exception("Just testing"); + logger.debug("Message " + ++i, e); + root.debug("Message " + i, e); + + logger.error("Message " + ++i, e); + root.error("Message " + i, e); + + Thread.currentThread().setName(oldThreadName); + } + + + /** + * CustomLogger implementation for testCategoryFactory1 and 2. + */ + private static class CustomLogger extends Logger { + /** + * Creates new instance. + * @param name logger name. + */ + public CustomLogger(final String name) { + super(name); + } + } + + /** + * Creates new instances of CustomLogger. + */ + public static class CustomLoggerFactory implements LoggerFactory { + /** + * Addivity, expected to be set false in configuration file. + */ + private boolean additivity; + + /** + * Create new instance of factory. + */ + public CustomLoggerFactory() { + additivity = true; + } + + /** + * Create new logger. + * @param name logger name. + * @return new logger. + */ + public Logger makeNewLoggerInstance(final String name) { + Logger logger = new CustomLogger(name); + assertFalse(additivity); + return logger; + } + + /** + * Set additivity. + * @param newVal new value of additivity. + */ + public void setAdditivity(final boolean newVal) { + additivity = newVal; + } + } + + /** + * CustomErrorHandler for testCategoryFactory2. + */ + public static class CustomErrorHandler implements ErrorHandler { + public CustomErrorHandler() {} + public void activateOptions() {} + public void setLogger(final Logger logger) {} + public void error(String message, Exception e, int errorCode) {} + public void error(String message) {} + public void error(String message, Exception e, int errorCode, LoggingEvent event) {} + public void setAppender(Appender appender) {} + public void setBackupAppender(Appender appender) {} + } + + /** + * Tests that loggers mentioned in logger elements + * use the specified categoryFactory. See bug 33708. + */ + public void testCategoryFactory1() { + DOMConfigurator.configure("input/xml/categoryfactory1.xml"); + // + // logger explicitly mentioned in configuration, + // should be a CustomLogger + Logger logger1 = Logger.getLogger("org.apache.log4j.xml.DOMTestCase.testCategoryFactory1.1"); + assertTrue(logger1 instanceof CustomLogger); + // + // logger not explicitly mentioned in configuration, + // should use default factory + Logger logger2 = Logger.getLogger("org.apache.log4j.xml.DOMTestCase.testCategoryFactory1.2"); + assertFalse(logger2 instanceof CustomLogger); + } + + /** + * Tests that loggers mentioned in logger-ref elements + * use the specified categoryFactory. See bug 33708. + */ + public void testCategoryFactory2() { + DOMConfigurator.configure("input/xml/categoryfactory2.xml"); + // + // logger explicitly mentioned in configuration, + // should be a CustomLogger + Logger logger1 = Logger.getLogger("org.apache.log4j.xml.DOMTestCase.testCategoryFactory2.1"); + assertTrue(logger1 instanceof CustomLogger); + // + // logger not explicitly mentioned in configuration, + // should use default factory + Logger logger2 = Logger.getLogger("org.apache.log4j.xml.DOMTestCase.testCategoryFactory2.2"); + assertFalse(logger2 instanceof CustomLogger); + } + + /** + * Tests that loggers mentioned in logger elements + * use the specified loggerFactory. See bug 33708. + */ + public void testLoggerFactory1() { + DOMConfigurator.configure("input/xml/loggerfactory1.xml"); + // + // logger explicitly mentioned in configuration, + // should be a CustomLogger + Logger logger1 = Logger.getLogger("org.apache.log4j.xml.DOMTestCase.testLoggerFactory1.1"); + assertTrue(logger1 instanceof CustomLogger); + // + // logger not explicitly mentioned in configuration, + // should use default factory + Logger logger2 = Logger.getLogger("org.apache.log4j.xml.DOMTestCase.testLoggerFactory1.2"); + assertFalse(logger2 instanceof CustomLogger); + } + + /** + * Tests that reset="true" on log4j:configuration element resets + * repository before configuration. + * @throws Exception thrown on error. + */ + public void testReset() throws Exception { + VectorAppender appender = new VectorAppender(); + appender.setName("V1"); + Logger.getRootLogger().addAppender(appender); + DOMConfigurator.configure("input/xml/testReset.xml"); + assertNull(Logger.getRootLogger().getAppender("V1")); + } + + + /** + * Test checks that configureAndWatch does initial configuration, see bug 33502. + * @throws Exception if IO error. + */ + public void testConfigureAndWatch() throws Exception { + DOMConfigurator.configureAndWatch("input/xml/DOMTestCase1.xml"); + assertNotNull(Logger.getRootLogger().getAppender("A1")); + } + + + /** + * This test checks that the subst method of an extending class + * is checked when evaluating parameters. See bug 43325. + * + */ + public void testOverrideSubst() { + DOMConfigurator configurator = new DOMConfigurator() { + protected String subst(final String value) { + if ("output/temp.A1".equals(value)) { + return "output/subst-test.A1"; + } + return value; + } + }; + configurator.doConfigure("input/xml/DOMTestCase1.xml", LogManager.getLoggerRepository()); + FileAppender a1 = (FileAppender) Logger.getRootLogger().getAppender("A1"); + String file = a1.getFile(); + assertEquals("output/subst-test.A1", file); + } + + /** + * Mock ThrowableRenderer for testThrowableRenderer. See bug 45721. + */ + public static class MockThrowableRenderer implements ThrowableRenderer, OptionHandler { + private boolean activated = false; + private boolean showVersion = true; + + public MockThrowableRenderer() { + } + + public void activateOptions() { + activated = true; + } + + public boolean isActivated() { + return activated; + } + + public String[] doRender(final Throwable t) { + return new String[0]; + } + + public void setShowVersion(boolean v) { + showVersion = v; + } + + public boolean getShowVersion() { + return showVersion; + } + } + + /** + * Test of log4j.throwableRenderer support. See bug 45721. + */ + public void testThrowableRenderer1() { + DOMConfigurator.configure("input/xml/throwableRenderer1.xml"); + ThrowableRendererSupport repo = (ThrowableRendererSupport) LogManager.getLoggerRepository(); + MockThrowableRenderer renderer = (MockThrowableRenderer) repo.getThrowableRenderer(); + LogManager.resetConfiguration(); + assertNotNull(renderer); + assertEquals(true, renderer.isActivated()); + assertEquals(false, renderer.getShowVersion()); + } + + /** + * Test for bug 47465. + * configure(URL) did not close opened JarURLConnection. + * @throws IOException if IOException creating properties jar. + */ + public void testJarURL() throws IOException { + File input = new File("input/xml/defaultInit.xml"); + System.out.println(input.getAbsolutePath()); + InputStream is = new FileInputStream(input); + File dir = new File("output"); + dir.mkdirs(); + File file = new File("output/xml.jar"); + ZipOutputStream zos = + new ZipOutputStream(new FileOutputStream(file)); + zos.putNextEntry(new ZipEntry("log4j.xml")); + int len; + byte[] buf = new byte[1024]; + while ((len = is.read(buf)) > 0) { + zos.write(buf, 0, len); + } + zos.closeEntry(); + zos.close(); + URL url = new URL("jar:" + file.toURL() + "!/log4j.xml"); + DOMConfigurator.configure(url); + assertTrue(file.delete()); + assertFalse(file.exists()); + } + +} diff --git a/tests/src/java/org/apache/log4j/xml/LoggerFactoryTest.java b/tests/src/java/org/apache/log4j/xml/LoggerFactoryTest.java deleted file mode 100644 index 26b675227a..0000000000 --- a/tests/src/java/org/apache/log4j/xml/LoggerFactoryTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.xml; - -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.joran.JoranConfigurator; -import org.apache.log4j.spi.LoggerFactory; - -import junit.framework.TestCase; - -public class LoggerFactoryTest extends TestCase { - - static boolean pass = false; - - public static class Factory implements LoggerFactory { - - public Logger makeNewLoggerInstance(String name) { - pass = true; - return new MyLogger(name); - } - - } - - public static class MyLogger extends Logger { - - protected MyLogger(String name) { - super(name); - } - - } - - public void testSelectLogFactory() - { - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure("input/xml/loggerFactory1.xml", LogManager.getLoggerRepository()); - Logger l = Logger.getLogger("x"); - assertEquals(MyLogger.class, l.getClass()); - assertEquals(true, pass); - pass = false; - - jc.doConfigure("input/xml/loggerFactory2.xml", LogManager.getLoggerRepository()); - Logger.getLogger("xy"); - assertEquals(true, pass); - } - -} diff --git a/tests/src/java/org/apache/log4j/xml/MockReceiver.java b/tests/src/java/org/apache/log4j/xml/MockReceiver.java deleted file mode 100644 index 45052021f3..0000000000 --- a/tests/src/java/org/apache/log4j/xml/MockReceiver.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.xml; - -import org.apache.log4j.plugins.PluginSkeleton; - -/** - * Mock receiver used by PluginConfiguratorTest. - */ -public final class MockReceiver extends PluginSkeleton { - /** - * Is active. - */ - private boolean active = false; - /** - * Host name. - */ - private String host; - /** - * Port. - */ - private int port = 0; - - /** - * Create new instance. - */ - public MockReceiver() { - super(); - } - - /** - * Shutdown. - */ - public void shutdown() { - active = false; - } - - /** - * Is plugin active. - * @return true if active. - */ - public boolean isActive() { - return active; - } - - /** - * Activate options. - */ - public void activateOptions() { - active = true; - } - - /** - Get the remote host to connect to for logging events. - @return host - */ - public String getHost() { - return host; - } - - /** - * Configures the Host property, this will require activateOptions - * to be called for this to take effect. - * @param remoteHost address of remote host. - */ - public void setHost(final String remoteHost) { - this.host = remoteHost; - } - /** - Set the remote host to connect to for logging events. - Equivalent to setHost. - @param remoteHost address of remote host. - */ - public void setPort(final String remoteHost) { - host = remoteHost; - } - - /** - Get the remote port to connect to for logging events. - @return port - */ - public int getPort() { - return port; - } - - /** - Set the remote port to connect to for logging events. - @param p port - */ - public void setPort(final int p) { - this.port = p; - } - -} diff --git a/tests/src/java/org/apache/log4j/xml/PluginConfiguratorTest.java b/tests/src/java/org/apache/log4j/xml/PluginConfiguratorTest.java deleted file mode 100644 index 5d774afc41..0000000000 --- a/tests/src/java/org/apache/log4j/xml/PluginConfiguratorTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.log4j.xml; - - -import junit.framework.TestCase; -import org.apache.log4j.LogManager; -import org.apache.log4j.spi.LoggerRepositoryEx; -import org.apache.log4j.plugins.*; - -import java.util.List; - -/** - * - * Tests for PluginConfigurator. - */ -public final class PluginConfiguratorTest extends TestCase { - - /** - * Create new instance. - * @param testName test name. - */ - public PluginConfiguratorTest(final String testName) { - super(testName); - } - - /** - * Test parsing a file containing a plugin element. - */ - public void testParse() { - PluginConfigurator.configure("input/xml/plugins1.xml"); - PluginRegistry plugins = - ((LoggerRepositoryEx) LogManager.getLoggerRepository()). - getPluginRegistry(); - assertTrue(plugins.pluginNameExists("mock1")); - List receivers = plugins.getPlugins( - org.apache.log4j.xml.MockReceiver.class); - assertEquals(1, receivers.size()); - MockReceiver mock1 = (MockReceiver) receivers.get(0); - assertEquals("mock1", mock1.getName()); - assertEquals("127.0.0.1", mock1.getHost()); - assertEquals(4560, mock1.getPort()); - assertTrue(mock1.isActive()); - plugins.stopAllPlugins(); - assertFalse(mock1.isActive()); - } -} diff --git a/tests/src/java/org/apache/log4j/xml/ResetTest.java b/tests/src/java/org/apache/log4j/xml/ResetTest.java deleted file mode 100644 index 0962952beb..0000000000 --- a/tests/src/java/org/apache/log4j/xml/ResetTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.apache.log4j.xml; - -import java.util.Properties; - -import org.apache.log4j.Level; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.PropertyConfigurator; -import org.apache.log4j.joran.JoranConfigurator; - -import junit.framework.TestCase; - -public class ResetTest extends TestCase { - - Logger logx; - - protected void setUp() { - LogManager.getLoggerRepository().resetConfiguration(); - initx(); - } - - public void testResetXml() { - test("tests/input/xml/defaultInit.xml", false); - test("tests/input/xml/resetTest.xml", true); - } - - private void initx() { - logx = Logger.getLogger("x"); - logx.setLevel(Level.ERROR); - assertEquals(Level.ERROR, logx.getLevel()); - } - - public void testResetProps() { - Properties p = new Properties(); - p.put("log4j.rootLogger","DEBUG,C"); - p.put("log4j.appender.C","org.apache.log4j.ConsoleAppender"); - p.put("log4j.appender.C","layout=org.apache.log4j.SimpleLayout"); - testProperties(p, false); - testProperties(p, true); - } - - private void test(String file, boolean reset) - { - JoranConfigurator jc = new JoranConfigurator(); - jc.doConfigure(file, LogManager.getLoggerRepository()); - if (reset) - assertEquals("reset=" + reset, null, logx.getLevel()); - else - assertEquals(Level.ERROR, logx.getLevel()); - } - - private void testProperties(Properties p, boolean reset) - { - if (reset) { - p.put("log4j.reset", "true"); - } else { - p.remove("log4j.reset"); - } - System.out.println(" --- test " + p); - PropertyConfigurator.configure(p); - if (reset) - assertEquals("reset=" + reset, null, logx.getLevel()); - else - assertEquals(Level.ERROR, logx.getLevel()); - } - - -} diff --git a/tests/src/java/org/apache/log4j/xml/XLevel.java b/tests/src/java/org/apache/log4j/xml/XLevel.java index 091492c115..bd8474f79a 100644 --- a/tests/src/java/org/apache/log4j/xml/XLevel.java +++ b/tests/src/java/org/apache/log4j/xml/XLevel.java @@ -26,53 +26,65 @@ */ public class XLevel extends Level { - private static final long serialVersionUID = 7288304330257085144L; - - public static final int TRACE_INT = Level.DEBUG_INT - 1; - public static final int LETHAL_INT = Level.FATAL_INT + 1; - private static String TRACE_STR = "TRACE"; - private static String LETHAL_STR = "LETHAL"; + + static public final int TRACE_INT = Level.DEBUG_INT - 1; + static public final int LETHAL_INT = Level.FATAL_INT + 1; + + + private static String TRACE_STR = "TRACE"; + private static String LETHAL_STR = "LETHAL"; + + public static final XLevel TRACE = new XLevel(TRACE_INT, TRACE_STR, 7); - public static final XLevel LETHAL = new XLevel(LETHAL_INT, LETHAL_STR, 0); + public static final XLevel LETHAL = new XLevel(LETHAL_INT, LETHAL_STR, + 0); - protected XLevel(int level, String strLevel, int syslogEquiv) { + + protected + XLevel(int level, String strLevel, int syslogEquiv) { super(level, strLevel, syslogEquiv); } /** Convert the string passed as argument to a level. If the - conversion fails, then this method returns {@link #TRACE}. + conversion fails, then this method returns {@link #TRACE}. */ - public static Level toLevel(String sArg) { - return (Level) toLevel(sArg, XLevel.TRACE); + public + static + Level toLevel(String sArg) { + return toLevel(sArg, XLevel.TRACE); } - public static Level toLevel(String sArg, Level defaultValue) { - if (sArg == null) { + + public + static + Level toLevel(String sArg, Level defaultValue) { + + if(sArg == null) { return defaultValue; } - String stringVal = sArg.toUpperCase(); - - if (stringVal.equals(TRACE_STR)) { + + if(stringVal.equals(TRACE_STR)) { return XLevel.TRACE; - } else if (stringVal.equals(LETHAL_STR)) { + } else if(stringVal.equals(LETHAL_STR)) { return XLevel.LETHAL; } - - return Level.toLevel(sArg, (Level) defaultValue); + + return Level.toLevel(sArg, defaultValue); } - public static Level toLevel(int i) throws IllegalArgumentException { - switch (i) { - case TRACE_INT: - return XLevel.TRACE; - case LETHAL_INT: - return XLevel.LETHAL; + public + static + Level toLevel(int i) throws IllegalArgumentException { + switch(i) { + case TRACE_INT: return XLevel.TRACE; + case LETHAL_INT: return XLevel.LETHAL; } - return Level.toLevel(i); } + } + diff --git a/tests/src/java/org/apache/log4j/xml/XMLDecoderTest.java b/tests/src/java/org/apache/log4j/xml/XMLDecoderTest.java deleted file mode 100644 index 84712525ad..0000000000 --- a/tests/src/java/org/apache/log4j/xml/XMLDecoderTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Created on 29/04/2003 - * - * To change the template for this generated file go to - * Window>Preferences>Java>Code Generation>Code and Comments - */ -package org.apache.log4j.xml; - -import java.io.File; -import java.util.List; - -import junit.framework.TestCase; - -import org.apache.log4j.xml.XMLDecoder; - -/** - * @author Paul Smith - * - */ -public class XMLDecoderTest extends TestCase { - - /** - * Constructor for XMLDecoderTest. - * @param arg0 - */ - public XMLDecoderTest(String arg0) { - super(arg0); - } - - /* - * Test for Vector decode(File) - */ - public void testDecodeFile() throws Exception { - XMLDecoder xmlDecoder = new XMLDecoder(); - List events = xmlDecoder.decode(new File("tests/witness/eventSet.1.xml").toURL()); - assertTrue("Should have returned at least 418 events: " + events.size(), events.size()==418); - - } - -} diff --git a/tests/src/java/org/apache/log4j/xml/XMLLayoutTest.java b/tests/src/java/org/apache/log4j/xml/XMLLayoutTest.java index 6ea2dd528b..a21c0222cb 100644 --- a/tests/src/java/org/apache/log4j/xml/XMLLayoutTest.java +++ b/tests/src/java/org/apache/log4j/xml/XMLLayoutTest.java @@ -28,11 +28,13 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; +import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import java.io.Reader; import java.io.StringReader; +import java.util.Hashtable; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -53,6 +55,23 @@ public XMLLayoutTest(final String testName) { super(testName, "text/plain", false, null, null); } + /** + * Clear MDC and NDC before test. + */ + public void setUp() { + NDC.clear(); + if (MDC.getContext() != null) { + MDC.getContext().clear(); + } + } + + /** + * Clear MDC and NDC after test. + */ + public void tearDown() { + setUp(); + } + /** * @{inheritDoc} */ @@ -87,10 +106,10 @@ private void checkEventElement( final Element element, final LoggingEvent event) { assertEquals("log4j:event", element.getTagName()); assertEquals( - "org.apache.log4j.xml.XMLLayoutTest", element.getAttribute("logger")); + event.getLoggerName(), element.getAttribute("logger")); assertEquals( Long.toString(event.timeStamp), element.getAttribute("timestamp")); - assertEquals("INFO", element.getAttribute("level")); + assertEquals(event.getLevel().toString(), element.getAttribute("level")); assertEquals(event.getThreadName(), element.getAttribute("thread")); } @@ -139,17 +158,40 @@ private void checkThrowableElement( assertEquals(Node.TEXT_NODE, messageNode.getNodeType()); String msg = ex.toString(); - assertEquals("Got " + messageNode.getNodeValue(), msg, messageNode.getNodeValue().substring(0, msg.length())); + assertEquals(msg, messageNode.getNodeValue().substring(0, msg.length())); assertNull(messageNode.getNextSibling()); } + /** + * Checks a log4j:properties element against expectations. + * @param element element, may not be null. + * @param key key. + * @param value value. + */ + private void checkPropertiesElement( + final Element element, final String key, final String value) { + assertEquals("log4j:properties", element.getTagName()); + + int childNodeCount = 0; + for(Node child = element.getFirstChild(); + child != null; + child = child.getNextSibling()) { + if (child.getNodeType() == Node.ELEMENT_NODE) { + assertEquals("log4j:data", child.getNodeName()); + Element childElement = (Element) child; + assertEquals(key, childElement.getAttribute("name")); + assertEquals(value, childElement.getAttribute("value")); + childNodeCount++; + } + } + assertEquals(1, childNodeCount); + } + /** * Tests formatted results. * @throws Exception if parser can not be constructed or source is not a valid XML document. */ public void testFormat() throws Exception { - MDC.clear(); - NDC.clear(); Logger logger = Logger.getLogger("org.apache.log4j.xml.XMLLayoutTest"); LoggingEvent event = new LoggingEvent( @@ -194,8 +236,6 @@ public void testFormat() throws Exception { * @throws Exception if parser can not be constructed or source is not a valid XML document. */ public void testFormatWithException() throws Exception { - MDC.clear(); - NDC.clear(); Logger logger = Logger.getLogger("org.apache.log4j.xml.XMLLayoutTest"); Exception ex = new IllegalArgumentException("'foo' is not a valid name"); LoggingEvent event = @@ -246,8 +286,6 @@ public void testFormatWithException() throws Exception { * @throws Exception if parser can not be constructed or source is not a valid XML document. */ public void testFormatWithNDC() throws Exception { - MDC.clear(); - NDC.clear(); Logger logger = Logger.getLogger("org.apache.log4j.xml.XMLLayoutTest"); NDC.push("NDC goes here"); @@ -315,4 +353,149 @@ public void testActivateOptions() { XMLLayout layout = new XMLLayout(); layout.activateOptions(); } + + /** + * Level with arbitrary toString value. + */ + private static final class ProblemLevel extends Level { + private static final long serialVersionUID = 1L; + /** + * Construct new instance. + * @param levelName level name, may not be null. + */ + public ProblemLevel(final String levelName) { + super(6000, levelName, 6); + } + } + + /** + * Tests problematic characters in multiple fields. + * @throws Exception if parser can not be constructed or source is not a valid XML document. + */ + public void testProblemCharacters() throws Exception { + String problemName = "com.example.bar<>&\"'"; + Logger logger = Logger.getLogger(problemName); + Level level = new ProblemLevel(problemName); + Exception ex = new IllegalArgumentException(problemName); + String threadName = Thread.currentThread().getName(); + Thread.currentThread().setName(problemName); + NDC.push(problemName); + Hashtable mdcMap = MDC.getContext(); + if (mdcMap != null) { + mdcMap.clear(); + } + MDC.put(problemName, problemName); + LoggingEvent event = + new LoggingEvent( + problemName, logger, level, problemName, ex); + XMLLayout layout = (XMLLayout) createLayout(); + layout.setProperties(true); + String result = layout.format(event); + mdcMap = MDC.getContext(); + if (mdcMap != null) { + mdcMap.clear(); + } + Thread.currentThread().setName(threadName); + + Element parsedResult = parse(result); + checkEventElement(parsedResult, event); + + int childElementCount = 0; + + for ( + Node node = parsedResult.getFirstChild(); node != null; + node = node.getNextSibling()) { + switch (node.getNodeType()) { + case Node.ELEMENT_NODE: + childElementCount++; + switch(childElementCount) { + case 1: + checkMessageElement((Element) node, problemName); + break; + + case 2: + checkNDCElement((Element) node, problemName); + break; + + case 3: + checkThrowableElement((Element) node, ex); + break; + + case 4: + checkPropertiesElement((Element) node, problemName, problemName); + break; + + default: + fail("Unexpected element"); + break; + } + + break; + + case Node.COMMENT_NODE: + break; + + case Node.TEXT_NODE: + + // should only be whitespace + break; + + default: + fail("Unexpected node type"); + + break; + } + } + } + + /** + * Tests CDATA element within NDC content. See bug 37560. + */ + public void testNDCWithCDATA() throws Exception { + Logger logger = Logger.getLogger("com.example.bar"); + Level level = Level.INFO; + String ndcMessage =""; + NDC.push(ndcMessage); + LoggingEvent event = + new LoggingEvent( + "com.example.bar", logger, level, "Hello, World", null); + Layout layout = createLayout(); + String result = layout.format(event); + NDC.clear(); + Element parsedResult = parse(result); + NodeList ndcs = parsedResult.getElementsByTagName("log4j:NDC"); + assertEquals(1, ndcs.getLength()); + StringBuffer buf = new StringBuffer(); + for(Node child = ndcs.item(0).getFirstChild(); + child != null; + child = child.getNextSibling()) { + buf.append(child.getNodeValue()); + } + assertEquals(ndcMessage, buf.toString()); + } + + /** + * Tests CDATA element within exception. See bug 37560. + */ + public void testExceptionWithCDATA() throws Exception { + Logger logger = Logger.getLogger("com.example.bar"); + Level level = Level.INFO; + String exceptionMessage =""; + LoggingEvent event = + new LoggingEvent( + "com.example.bar", logger, level, "Hello, World", new Exception(exceptionMessage)); + Layout layout = createLayout(); + String result = layout.format(event); + Element parsedResult = parse(result); + NodeList throwables = parsedResult.getElementsByTagName("log4j:throwable"); + assertEquals(1, throwables.getLength()); + StringBuffer buf = new StringBuffer(); + for(Node child = throwables.item(0).getFirstChild(); + child != null; + child = child.getNextSibling()) { + buf.append(child.getNodeValue()); + } + assertTrue(buf.toString().indexOf(exceptionMessage) != -1); + } + } diff --git a/tests/src/java/org/apache/log4j/xml/XMLLayoutTestCase.java b/tests/src/java/org/apache/log4j/xml/XMLLayoutTestCase.java index 6b7c4b6e7f..e76acd6b19 100644 --- a/tests/src/java/org/apache/log4j/xml/XMLLayoutTestCase.java +++ b/tests/src/java/org/apache/log4j/xml/XMLLayoutTestCase.java @@ -20,7 +20,6 @@ import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; - import org.apache.log4j.FileAppender; import org.apache.log4j.Level; import org.apache.log4j.Logger; @@ -32,15 +31,16 @@ import org.apache.log4j.util.SunReflectFilter; import org.apache.log4j.util.Transformer; import org.apache.log4j.util.XMLLineAttributeFilter; -import org.apache.log4j.util.XMLSequenceNumberFilter; import org.apache.log4j.util.XMLTimestampFilter; -import org.apache.log4j.xml.XMLLayout; +import java.util.Hashtable; public class XMLLayoutTestCase extends TestCase { + static String TEMP = "output/temp"; static String FILTERED = "output/filtered"; - Logger root; + + Logger root; Logger logger; public XMLLayoutTestCase(String name) { @@ -49,10 +49,12 @@ public XMLLayoutTestCase(String name) { public void setUp() { root = Logger.getRootLogger(); + root.setLevel(Level.TRACE); logger = Logger.getLogger(XMLLayoutTestCase.class); + logger.setLevel(Level.TRACE); } - public void tearDown() { + public void tearDown() { root.getLoggerRepository().resetConfiguration(); } @@ -64,12 +66,11 @@ public void basic() throws Exception { TEMP, FILTERED, new Filter[] { new LineNumberFilter(), + new XMLTimestampFilter(), new JunitTestRunnerFilter(), - new XMLTimestampFilter(), - new XMLSequenceNumberFilter(), new SunReflectFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/xml/xmlLayout.1")); + assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.1")); } public void locationInfo() throws Exception { @@ -80,13 +81,13 @@ public void locationInfo() throws Exception { Transformer.transform( TEMP, FILTERED, new Filter[] { - new LineNumberFilter(), + new LineNumberFilter(), + new XMLTimestampFilter(), + new XMLLineAttributeFilter(), new JunitTestRunnerFilter(), - new XMLTimestampFilter(), - new XMLSequenceNumberFilter(), - new XMLLineAttributeFilter(), new SunReflectFilter() + new SunReflectFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/xml/xmlLayout.2")); + assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.2")); } public void testCDATA() throws Exception { @@ -94,105 +95,136 @@ public void testCDATA() throws Exception { xmlLayout.setLocationInfo(true); root.addAppender(new FileAppender(xmlLayout, TEMP, false)); + String oldThreadName = Thread.currentThread().getName(); + Thread.currentThread().setName("main"); + + logger.trace("Message with embedded hi]]>."); logger.debug("Message with embedded hi]]>."); + Thread.currentThread().setName(oldThreadName); + Transformer.transform( TEMP, FILTERED, new Filter[] { new LineNumberFilter(), - new JunitTestRunnerFilter(), new XMLTimestampFilter(), - new XMLSequenceNumberFilter(), - new XMLLineAttributeFilter(), new SunReflectFilter() + new XMLLineAttributeFilter(), + new SunReflectFilter(), + new JunitTestRunnerFilter() + }); - assertTrue(Compare.compare(FILTERED, "witness/xml/xmlLayout.3")); + Transformer.transform(TEMP, FILTERED, new Filter[] {new LineNumberFilter(), + new XMLTimestampFilter(), + new XMLLineAttributeFilter()}); + assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.3")); } public void testNull() throws Exception { XMLLayout xmlLayout = new XMLLayout(); root.addAppender(new FileAppender(xmlLayout, TEMP, false)); + + String oldThreadName = Thread.currentThread().getName(); + Thread.currentThread().setName("main"); + logger.debug("hi"); logger.debug(null); - Exception e = new Exception((String) null); logger.debug("hi", e); - Transformer.transform( - TEMP, FILTERED, - new Filter[] { new LineNumberFilter(), - new JunitTestRunnerFilter(), - new SunReflectFilter(), - new XMLTimestampFilter(), - new XMLSequenceNumberFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/xml/xmlLayout.null")); - } - - /** - * Tests the format of the MDC portion of the layout to ensure - * the key-value pairs we put in turn up in the output file. - * @throws Exception - */ - public void testMDC() throws Exception { - XMLLayout xmlLayout = new XMLLayout(); - root.addAppender(new FileAppender(xmlLayout, TEMP, false)); - MDC.clear(); - MDC.put("key1", "val1"); - MDC.put("key2", "val2"); + Thread.currentThread().setName(oldThreadName); - logger.debug("Hello"); Transformer.transform( TEMP, FILTERED, - new Filter[] { new LineNumberFilter(), + new Filter[] { new LineNumberFilter(), + new XMLTimestampFilter(), new JunitTestRunnerFilter(), - new XMLTimestampFilter(), - new XMLSequenceNumberFilter()}); - assertTrue(Compare.compare(FILTERED, "witness/xml/xmlLayout.mdc.1")); + new SunReflectFilter()}); + assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.null")); } - public void holdTestMDCEscaped() throws Exception { - XMLLayout xmlLayout = new XMLLayout(); - root.addAppender(new FileAppender(xmlLayout, TEMP, false)); - - MDC.clear(); - MDC.put("blahAttribute", ""); - MDC.put("", "blahValue"); + /** + * Tests the format of the MDC portion of the layout to ensure + * the key-value pairs we put in turn up in the output file. + * @throws Exception + */ + public void testMDC() throws Exception { + XMLLayout xmlLayout = new XMLLayout(); + xmlLayout.setProperties(true); + root.addAppender(new FileAppender(xmlLayout, TEMP, false)); + + Hashtable context = MDC.getContext(); + if (context != null) { + context.clear(); + } + MDC.put("key1", "val1"); + MDC.put("key2", "val2"); + + logger.debug("Hello"); + Transformer.transform( + TEMP, FILTERED, + new Filter[] { new LineNumberFilter(), + new JunitTestRunnerFilter(), + new XMLTimestampFilter()}); + assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.mdc.1")); + } - logger.debug("Hello"); - Transformer.transform( - TEMP, FILTERED, - new Filter[] { new LineNumberFilter(), - new JunitTestRunnerFilter(), - new XMLTimestampFilter(), - new XMLSequenceNumberFilter() }); - assertTrue(Compare.compare(FILTERED, "witness/xml/xmlLayout.mdc.2")); - } + public void testMDCEscaped() throws Exception { + XMLLayout xmlLayout = new XMLLayout(); + xmlLayout.setProperties(true); + root.addAppender(new FileAppender(xmlLayout, TEMP, false)); + + Hashtable context = MDC.getContext(); + if (context != null) { + context.clear(); + } + MDC.put("blahAttribute", ""); + MDC.put("", "blahValue"); + + logger.debug("Hello"); + Transformer.transform( + TEMP, FILTERED, + new Filter[] { new LineNumberFilter(), + new JunitTestRunnerFilter(), + new XMLTimestampFilter() }); + assertTrue(Compare.compare(FILTERED, "witness/xmlLayout.mdc.2")); + } + void common() { + String oldThreadName = Thread.currentThread().getName(); + Thread.currentThread().setName("main"); + int i = -1; + + new X(); - X x = new X(); + logger.trace("Message " + ++i); + root.trace("Message " + i); logger.debug("Message " + ++i); - root.debug("Message " + i); + root.debug("Message " + i); logger.info("Message " + ++i); - root.info("Message " + i); - - logger.warn("Message " + ++i); - root.warn("Message " + i); + root.info("Message " + i); + logger.warn ("Message " + ++i); + root.warn("Message " + i); + logger.error("Message " + ++i); root.error("Message " + i); - + logger.log(Level.FATAL, "Message " + ++i); - root.log(Level.FATAL, "Message " + i); - + root.log(Level.FATAL, "Message " + i); + Exception e = new Exception("Just testing"); logger.debug("Message " + ++i, e); root.debug("Message " + i, e); - + logger.error("Message " + ++i, e); - root.error("Message " + i, e); + root.error("Message " + i, e); + + + Thread.currentThread().setName(oldThreadName); } public static Test suite() { @@ -202,13 +234,13 @@ public static Test suite() { suite.addTest(new XMLLayoutTestCase("testCDATA")); suite.addTest(new XMLLayoutTestCase("testNull")); suite.addTest(new XMLLayoutTestCase("testMDC")); - + suite.addTest(new XMLLayoutTestCase("testMDCEscaped")); return suite; } + class X { Logger logger = Logger.getLogger(X.class); - public X() { logger.info("in X() constructor"); } diff --git a/src/sun_checks.xml b/tests/sun_checks.xml similarity index 82% rename from src/sun_checks.xml rename to tests/sun_checks.xml index 2385ae1c3f..71b31c3f64 100644 --- a/src/sun_checks.xml +++ b/tests/sun_checks.xml @@ -2,6 +2,23 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - These are some of the targets supported by this ANT build scpript: - - build - compile all project files, if a certain library is missing, - then the compilation of its dependents are skipped. - - runAll - run all available tests - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/webapps/Tata/.cvsignore b/tests/webapps/Tata/.cvsignore deleted file mode 100644 index 1897fee99f..0000000000 --- a/tests/webapps/Tata/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -classes -build.properties -tata.war \ No newline at end of file diff --git a/tests/webapps/Tata/build.properties.sample b/tests/webapps/Tata/build.properties.sample deleted file mode 100644 index 3754ad70d2..0000000000 --- a/tests/webapps/Tata/build.properties.sample +++ /dev/null @@ -1,6 +0,0 @@ -# Sample build.properties file - -# We need servlet to compile the various servlets. -servlet.jar=../../lib/javax.servlet.jar - - diff --git a/tests/webapps/Tata/build.xml b/tests/webapps/Tata/build.xml deleted file mode 100644 index e5bd8a271c..0000000000 --- a/tests/webapps/Tata/build.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/webapps/Tata/src/WEB-INF/web.xml b/tests/webapps/Tata/src/WEB-INF/web.xml deleted file mode 100644 index 8a88fd8f86..0000000000 --- a/tests/webapps/Tata/src/WEB-INF/web.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - some-init-servlet - wombat.InitServlet - 1 - - - - - XServlet - wombat.XServlet - - - - XServlet - /XServlet - - - - A JNDI test entry - my-entry - tata - java.lang.String - - - diff --git a/tests/webapps/Tata/src/html/index.html b/tests/webapps/Tata/src/html/index.html deleted file mode 100644 index f4176b4a26..0000000000 --- a/tests/webapps/Tata/src/html/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - -

    -This will call Tata. - -
    - - - \ No newline at end of file diff --git a/tests/webapps/Tata/src/java/wombat/InitServlet.java b/tests/webapps/Tata/src/java/wombat/InitServlet.java deleted file mode 100644 index a9ac28ca7e..0000000000 --- a/tests/webapps/Tata/src/java/wombat/InitServlet.java +++ /dev/null @@ -1,16 +0,0 @@ -package wombat; - -import javax.servlet.http.*; -import javax.servlet.*; - -public class InitServlet extends HttpServlet { - - public void init() { - //System.out.println("TATA wombat.InitServlet.init() called."); - } - - public void doGet(HttpServletRequest req, HttpServletResponse res) { - // nothing to do - } -} - diff --git a/tests/webapps/Tata/src/java/wombat/XServlet.java b/tests/webapps/Tata/src/java/wombat/XServlet.java deleted file mode 100644 index 10e7d69aa6..0000000000 --- a/tests/webapps/Tata/src/java/wombat/XServlet.java +++ /dev/null @@ -1,29 +0,0 @@ - -package wombat; - -import java.io.*; -import javax.servlet.*; -import javax.servlet.http.*; -import wombat.Util; - -public class XServlet extends HttpServlet { - - static final String MY_ENTRY = "java:comp/env/my-entry"; - - public void init() throws ServletException { - ServletContext context = getServletConfig().getServletContext(); - } - - - public void service(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - - response.setContentType("text/html"); - PrintWriter out = response.getWriter(); - - String result = Util.foo(MY_ENTRY); - - out.println(result); - out.close(); - } -} diff --git a/tests/webapps/Titi/.cvsignore b/tests/webapps/Titi/.cvsignore deleted file mode 100644 index 1897fee99f..0000000000 --- a/tests/webapps/Titi/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -classes -build.properties -tata.war \ No newline at end of file diff --git a/tests/webapps/Titi/build.properties.sample b/tests/webapps/Titi/build.properties.sample deleted file mode 100644 index 3754ad70d2..0000000000 --- a/tests/webapps/Titi/build.properties.sample +++ /dev/null @@ -1,6 +0,0 @@ -# Sample build.properties file - -# We need servlet to compile the various servlets. -servlet.jar=../../lib/javax.servlet.jar - - diff --git a/tests/webapps/Titi/build.xml b/tests/webapps/Titi/build.xml deleted file mode 100644 index e625de18ea..0000000000 --- a/tests/webapps/Titi/build.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/webapps/Titi/src/WEB-INF/web.xml b/tests/webapps/Titi/src/WEB-INF/web.xml deleted file mode 100644 index d254f82e6d..0000000000 --- a/tests/webapps/Titi/src/WEB-INF/web.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - some-init-servlet - wombat.InitServlet - 1 - - - - - XServlet - wombat.XServlet - - - - XServlet - /XServlet - - - - A JNDI test entry - my-entry - titi - java.lang.String - - - diff --git a/tests/webapps/Titi/src/html/index.html b/tests/webapps/Titi/src/html/index.html deleted file mode 100644 index f4176b4a26..0000000000 --- a/tests/webapps/Titi/src/html/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - -
    -This will call Tata. - -
    - - - \ No newline at end of file diff --git a/tests/webapps/Titi/src/java/wombat/InitServlet.java b/tests/webapps/Titi/src/java/wombat/InitServlet.java deleted file mode 100644 index a9ac28ca7e..0000000000 --- a/tests/webapps/Titi/src/java/wombat/InitServlet.java +++ /dev/null @@ -1,16 +0,0 @@ -package wombat; - -import javax.servlet.http.*; -import javax.servlet.*; - -public class InitServlet extends HttpServlet { - - public void init() { - //System.out.println("TATA wombat.InitServlet.init() called."); - } - - public void doGet(HttpServletRequest req, HttpServletResponse res) { - // nothing to do - } -} - diff --git a/tests/webapps/Titi/src/java/wombat/XServlet.java b/tests/webapps/Titi/src/java/wombat/XServlet.java deleted file mode 100644 index 10e7d69aa6..0000000000 --- a/tests/webapps/Titi/src/java/wombat/XServlet.java +++ /dev/null @@ -1,29 +0,0 @@ - -package wombat; - -import java.io.*; -import javax.servlet.*; -import javax.servlet.http.*; -import wombat.Util; - -public class XServlet extends HttpServlet { - - static final String MY_ENTRY = "java:comp/env/my-entry"; - - public void init() throws ServletException { - ServletContext context = getServletConfig().getServletContext(); - } - - - public void service(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - - response.setContentType("text/html"); - PrintWriter out = response.getWriter(); - - String result = Util.foo(MY_ENTRY); - - out.println(result); - out.close(); - } -} diff --git a/tests/webapps/Titi/titi.war b/tests/webapps/Titi/titi.war deleted file mode 100644 index a16302b0e0..0000000000 Binary files a/tests/webapps/Titi/titi.war and /dev/null differ diff --git a/tests/webapps/Util/.cvsignore b/tests/webapps/Util/.cvsignore deleted file mode 100644 index 1897fee99f..0000000000 --- a/tests/webapps/Util/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -classes -build.properties -tata.war \ No newline at end of file diff --git a/tests/webapps/Util/build.properties.sample b/tests/webapps/Util/build.properties.sample deleted file mode 100644 index ff7bce0da9..0000000000 --- a/tests/webapps/Util/build.properties.sample +++ /dev/null @@ -1,11 +0,0 @@ -# Sample build.properties file - -# The path to the web-server home -webserver.home=/java/tomcat/ - -# The deployment target directory on the web server -target.webapp.dir=${webserver.home}/webapps - -# We need servlet to compile the various servlets. -servlet.jar=/java/servlet.jar - diff --git a/tests/webapps/Util/build.xml b/tests/webapps/Util/build.xml deleted file mode 100644 index 431a8fdb74..0000000000 --- a/tests/webapps/Util/build.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/webapps/Util/src/java/wombat/Util.java b/tests/webapps/Util/src/java/wombat/Util.java deleted file mode 100644 index cd5cbd51b3..0000000000 --- a/tests/webapps/Util/src/java/wombat/Util.java +++ /dev/null @@ -1,39 +0,0 @@ - -package wombat; - -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; - -public class Util { - - static public String foo(String name) { - System.out.println("Util.foo() called"); - - Context ctx = null; - - try { - Initial ictx = new InitialContext(); - System.out.println("ctx type is "+ctx); - return (String) lookup(ctx, name); - } catch (NamingException ne) { - ne.printStackTrace(); - return null; - } - - } - - - static public String lookup(Context ctx, String name) { - if(ctx == null) { - return null; - } - try { - return (String) ctx.lookup(name); - } catch (NamingException ne) { - System.out.println("Could not find ["+name+"]"); - ne.printStackTrace(); - return null; - } - } -} diff --git a/tests/webapps/Util/util.jar b/tests/webapps/Util/util.jar deleted file mode 100644 index 68f971b4a7..0000000000 Binary files a/tests/webapps/Util/util.jar and /dev/null differ diff --git a/tests/witness/LevelMatchFilter_accept b/tests/witness/LevelMatchFilter_accept index a6a4d484a5..14c0b245bc 100644 --- a/tests/witness/LevelMatchFilter_accept +++ b/tests/witness/LevelMatchFilter_accept @@ -1,5 +1,6 @@ -DEBUG - pass 0; filter set to accept only DEBUG msgs -INFO - pass 1; filter set to accept only INFO msgs -WARN - pass 2; filter set to accept only WARN msgs -ERROR - pass 3; filter set to accept only ERROR msgs -FATAL - pass 4; filter set to accept only FATAL msgs +TRACE - pass 0; filter set to accept only TRACE msgs +DEBUG - pass 1; filter set to accept only DEBUG msgs +INFO - pass 2; filter set to accept only INFO msgs +WARN - pass 3; filter set to accept only WARN msgs +ERROR - pass 4; filter set to accept only ERROR msgs +FATAL - pass 5; filter set to accept only FATAL msgs diff --git a/tests/witness/LevelMatchFilter_deny b/tests/witness/LevelMatchFilter_deny index 5273424d4c..3755855736 100644 --- a/tests/witness/LevelMatchFilter_deny +++ b/tests/witness/LevelMatchFilter_deny @@ -1,20 +1,30 @@ -INFO - pass 0; filter set to deny only DEBUG msgs -WARN - pass 0; filter set to deny only DEBUG msgs -ERROR - pass 0; filter set to deny only DEBUG msgs -FATAL - pass 0; filter set to deny only DEBUG msgs -DEBUG - pass 1; filter set to deny only INFO msgs -WARN - pass 1; filter set to deny only INFO msgs -ERROR - pass 1; filter set to deny only INFO msgs -FATAL - pass 1; filter set to deny only INFO msgs -DEBUG - pass 2; filter set to deny only WARN msgs -INFO - pass 2; filter set to deny only WARN msgs -ERROR - pass 2; filter set to deny only WARN msgs -FATAL - pass 2; filter set to deny only WARN msgs -DEBUG - pass 3; filter set to deny only ERROR msgs -INFO - pass 3; filter set to deny only ERROR msgs -WARN - pass 3; filter set to deny only ERROR msgs -FATAL - pass 3; filter set to deny only ERROR msgs -DEBUG - pass 4; filter set to deny only FATAL msgs -INFO - pass 4; filter set to deny only FATAL msgs -WARN - pass 4; filter set to deny only FATAL msgs -ERROR - pass 4; filter set to deny only FATAL msgs +DEBUG - pass 0; filter set to deny only TRACE msgs +INFO - pass 0; filter set to deny only TRACE msgs +WARN - pass 0; filter set to deny only TRACE msgs +ERROR - pass 0; filter set to deny only TRACE msgs +FATAL - pass 0; filter set to deny only TRACE msgs +TRACE - pass 1; filter set to deny only DEBUG msgs +INFO - pass 1; filter set to deny only DEBUG msgs +WARN - pass 1; filter set to deny only DEBUG msgs +ERROR - pass 1; filter set to deny only DEBUG msgs +FATAL - pass 1; filter set to deny only DEBUG msgs +TRACE - pass 2; filter set to deny only INFO msgs +DEBUG - pass 2; filter set to deny only INFO msgs +WARN - pass 2; filter set to deny only INFO msgs +ERROR - pass 2; filter set to deny only INFO msgs +FATAL - pass 2; filter set to deny only INFO msgs +TRACE - pass 3; filter set to deny only WARN msgs +DEBUG - pass 3; filter set to deny only WARN msgs +INFO - pass 3; filter set to deny only WARN msgs +ERROR - pass 3; filter set to deny only WARN msgs +FATAL - pass 3; filter set to deny only WARN msgs +TRACE - pass 4; filter set to deny only ERROR msgs +DEBUG - pass 4; filter set to deny only ERROR msgs +INFO - pass 4; filter set to deny only ERROR msgs +WARN - pass 4; filter set to deny only ERROR msgs +FATAL - pass 4; filter set to deny only ERROR msgs +TRACE - pass 5; filter set to deny only FATAL msgs +DEBUG - pass 5; filter set to deny only FATAL msgs +INFO - pass 5; filter set to deny only FATAL msgs +WARN - pass 5; filter set to deny only FATAL msgs +ERROR - pass 5; filter set to deny only FATAL msgs diff --git a/tests/witness/LevelRangeFilter_accept b/tests/witness/LevelRangeFilter_accept deleted file mode 100644 index eff4c7eddb..0000000000 --- a/tests/witness/LevelRangeFilter_accept +++ /dev/null @@ -1,46 +0,0 @@ -DEBUG - pass 0; no min or max set -INFO - pass 0; no min or max set -WARN - pass 0; no min or max set -ERROR - pass 0; no min or max set -FATAL - pass 0; no min or max set -WARN - pass 1; min set to WARN, max not set -ERROR - pass 1; min set to WARN, max not set -FATAL - pass 1; min set to WARN, max not set -DEBUG - pass 2; min not set, max set to WARN -INFO - pass 2; min not set, max set to WARN -WARN - pass 2; min not set, max set to WARN -DEBUG - pass 3; filter set to accept between DEBUG and FATAL msgs -INFO - pass 3; filter set to accept between DEBUG and FATAL msgs -WARN - pass 3; filter set to accept between DEBUG and FATAL msgs -ERROR - pass 3; filter set to accept between DEBUG and FATAL msgs -FATAL - pass 3; filter set to accept between DEBUG and FATAL msgs -DEBUG - pass 4; filter set to accept between DEBUG and ERROR msgs -INFO - pass 4; filter set to accept between DEBUG and ERROR msgs -WARN - pass 4; filter set to accept between DEBUG and ERROR msgs -ERROR - pass 4; filter set to accept between DEBUG and ERROR msgs -DEBUG - pass 5; filter set to accept between DEBUG and WARN msgs -INFO - pass 5; filter set to accept between DEBUG and WARN msgs -WARN - pass 5; filter set to accept between DEBUG and WARN msgs -DEBUG - pass 6; filter set to accept between DEBUG and INFO msgs -INFO - pass 6; filter set to accept between DEBUG and INFO msgs -DEBUG - pass 7; filter set to accept between DEBUG and DEBUG msgs -INFO - pass 8; filter set to accept between INFO and FATAL msgs -WARN - pass 8; filter set to accept between INFO and FATAL msgs -ERROR - pass 8; filter set to accept between INFO and FATAL msgs -FATAL - pass 8; filter set to accept between INFO and FATAL msgs -INFO - pass 9; filter set to accept between INFO and ERROR msgs -WARN - pass 9; filter set to accept between INFO and ERROR msgs -ERROR - pass 9; filter set to accept between INFO and ERROR msgs -INFO - pass 10; filter set to accept between INFO and WARN msgs -WARN - pass 10; filter set to accept between INFO and WARN msgs -INFO - pass 11; filter set to accept between INFO and INFO msgs -WARN - pass 13; filter set to accept between WARN and FATAL msgs -ERROR - pass 13; filter set to accept between WARN and FATAL msgs -FATAL - pass 13; filter set to accept between WARN and FATAL msgs -WARN - pass 14; filter set to accept between WARN and ERROR msgs -ERROR - pass 14; filter set to accept between WARN and ERROR msgs -WARN - pass 15; filter set to accept between WARN and WARN msgs -ERROR - pass 18; filter set to accept between ERROR and FATAL msgs -FATAL - pass 18; filter set to accept between ERROR and FATAL msgs -ERROR - pass 19; filter set to accept between ERROR and ERROR msgs -FATAL - pass 23; filter set to accept between FATAL and FATAL msgs diff --git a/tests/witness/LevelRangeFilter_neutral b/tests/witness/LevelRangeFilter_neutral deleted file mode 100644 index eff4c7eddb..0000000000 --- a/tests/witness/LevelRangeFilter_neutral +++ /dev/null @@ -1,46 +0,0 @@ -DEBUG - pass 0; no min or max set -INFO - pass 0; no min or max set -WARN - pass 0; no min or max set -ERROR - pass 0; no min or max set -FATAL - pass 0; no min or max set -WARN - pass 1; min set to WARN, max not set -ERROR - pass 1; min set to WARN, max not set -FATAL - pass 1; min set to WARN, max not set -DEBUG - pass 2; min not set, max set to WARN -INFO - pass 2; min not set, max set to WARN -WARN - pass 2; min not set, max set to WARN -DEBUG - pass 3; filter set to accept between DEBUG and FATAL msgs -INFO - pass 3; filter set to accept between DEBUG and FATAL msgs -WARN - pass 3; filter set to accept between DEBUG and FATAL msgs -ERROR - pass 3; filter set to accept between DEBUG and FATAL msgs -FATAL - pass 3; filter set to accept between DEBUG and FATAL msgs -DEBUG - pass 4; filter set to accept between DEBUG and ERROR msgs -INFO - pass 4; filter set to accept between DEBUG and ERROR msgs -WARN - pass 4; filter set to accept between DEBUG and ERROR msgs -ERROR - pass 4; filter set to accept between DEBUG and ERROR msgs -DEBUG - pass 5; filter set to accept between DEBUG and WARN msgs -INFO - pass 5; filter set to accept between DEBUG and WARN msgs -WARN - pass 5; filter set to accept between DEBUG and WARN msgs -DEBUG - pass 6; filter set to accept between DEBUG and INFO msgs -INFO - pass 6; filter set to accept between DEBUG and INFO msgs -DEBUG - pass 7; filter set to accept between DEBUG and DEBUG msgs -INFO - pass 8; filter set to accept between INFO and FATAL msgs -WARN - pass 8; filter set to accept between INFO and FATAL msgs -ERROR - pass 8; filter set to accept between INFO and FATAL msgs -FATAL - pass 8; filter set to accept between INFO and FATAL msgs -INFO - pass 9; filter set to accept between INFO and ERROR msgs -WARN - pass 9; filter set to accept between INFO and ERROR msgs -ERROR - pass 9; filter set to accept between INFO and ERROR msgs -INFO - pass 10; filter set to accept between INFO and WARN msgs -WARN - pass 10; filter set to accept between INFO and WARN msgs -INFO - pass 11; filter set to accept between INFO and INFO msgs -WARN - pass 13; filter set to accept between WARN and FATAL msgs -ERROR - pass 13; filter set to accept between WARN and FATAL msgs -FATAL - pass 13; filter set to accept between WARN and FATAL msgs -WARN - pass 14; filter set to accept between WARN and ERROR msgs -ERROR - pass 14; filter set to accept between WARN and ERROR msgs -WARN - pass 15; filter set to accept between WARN and WARN msgs -ERROR - pass 18; filter set to accept between ERROR and FATAL msgs -FATAL - pass 18; filter set to accept between ERROR and FATAL msgs -ERROR - pass 19; filter set to accept between ERROR and ERROR msgs -FATAL - pass 23; filter set to accept between FATAL and FATAL msgs diff --git a/tests/witness/NDCMatchFilter_accept b/tests/witness/NDCMatchFilter_accept deleted file mode 100644 index 4bac4205ec..0000000000 --- a/tests/witness/NDCMatchFilter_accept +++ /dev/null @@ -1,11 +0,0 @@ -pass 0: "level_1" exactly matches "level_1" -pass 1: "level_1 level_2" exactly matches "level_1 level_2" -pass 2: "level_1 level_2 level_3" exactly matches "level_1 level_2 level_3" -pass 3: "level_1" contained in "level_1 level_2 level_3" -pass 3: "level_1" contained in "level_1 level_2" -pass 3: "level_1" contained in "level_1" -pass 4: "level_1 level_2" contained in "level_1 level_2 level_3" -pass 4: "level_1 level_2" contained in "level_1 level_2" -pass 5: "level_1 level_2 level_3" contained in "level_1 level_2 level_3" -pass 6: "" exactly matches "" -pass 7: "" contained in "" diff --git a/tests/witness/NDCMatchFilter_deny b/tests/witness/NDCMatchFilter_deny deleted file mode 100644 index 055f2b6072..0000000000 --- a/tests/witness/NDCMatchFilter_deny +++ /dev/null @@ -1,21 +0,0 @@ -pass 0: "level_1" does not exactly match "level_1 level_2 level_3" -pass 0: "level_1" does not exactly match "level_1 level_2" -pass 0: "level_1" does not exactly match "" -pass 1: "level_1 level_2" does not exactly match "level_1 level_2 level_3" -pass 1: "level_1 level_2" does not exactly match "level_1" -pass 1: "level_1 level_2" does not exactly match "" -pass 2: "level_1 level_2 level_3" does not exactly match "level_1 level_2" -pass 2: "level_1 level_2 level_3" does not exactly match "level_1" -pass 2: "level_1 level_2 level_3" does not exactly match "" -pass 3: "level_1" not contained in "" -pass 4: "level_1 level_2" not contained in "level_1" -pass 4: "level_1 level_2" not contained in "" -pass 5: "level_1 level_2 level_3" not contained in "level_1 level_2" -pass 5: "level_1 level_2 level_3" not contained in "level_1" -pass 5: "level_1 level_2 level_3" not contained in "" -pass 6: "" does not exactly match "level_1 level_2 level_3" -pass 6: "" does not exactly match "level_1 level_2" -pass 6: "" does not exactly match "level_1" -pass 7: "" not contained in "level_1 level_2 level_3" -pass 7: "" not contained in "level_1 level_2" -pass 7: "" not contained in "level_1" diff --git a/tests/witness/PatternParser_mdc b/tests/witness/PatternParser_mdc new file mode 100644 index 0000000000..c7104dc38c --- /dev/null +++ b/tests/witness/PatternParser_mdc @@ -0,0 +1,12 @@ +starting mdc pattern test +empty mdc, no key specified in pattern : {} +empty mdc, key1 in pattern : +empty mdc, key2 in pattern : +empty mdc, key3 in pattern : +empty mdc, key1, key2, and key3 in pattern : ,, +filled mdc, no key specified in pattern : {{key1,value1}{key2,value2}} +filled mdc, key1 in pattern : value1 +filled mdc, key2 in pattern : value2 +filled mdc, key3 in pattern : +filled mdc, key1, key2, and key3 in pattern : value1,value2, +finished mdc pattern test diff --git a/tests/witness/compress1.txt.gz b/tests/witness/compress1.txt.gz deleted file mode 100644 index 1da4e4b072..0000000000 Binary files a/tests/witness/compress1.txt.gz and /dev/null differ diff --git a/tests/witness/compress2.txt.gz b/tests/witness/compress2.txt.gz deleted file mode 100644 index b33b98bf59..0000000000 Binary files a/tests/witness/compress2.txt.gz and /dev/null differ diff --git a/tests/witness/xml/customLevel.1 b/tests/witness/customLevel.1 similarity index 97% rename from tests/witness/xml/customLevel.1 rename to tests/witness/customLevel.1 index bdf641d96d..fc957b2f60 100644 --- a/tests/witness/xml/customLevel.1 +++ b/tests/witness/customLevel.1 @@ -1,5 +1,5 @@ -DEBUG xml.CustomLevelTestCase - Message 1 -INFO xml.CustomLevelTestCase - Message 2 -WARN xml.CustomLevelTestCase - Message 3 -ERROR xml.CustomLevelTestCase - Message 4 -TRACE xml.CustomLevelTestCase - Message 5 +DEBUG xml.CustomLevelTestCase - Message 1 +INFO xml.CustomLevelTestCase - Message 2 +WARN xml.CustomLevelTestCase - Message 3 +ERROR xml.CustomLevelTestCase - Message 4 +TRACE xml.CustomLevelTestCase - Message 5 diff --git a/tests/witness/xml/customLevel.2 b/tests/witness/customLevel.2 similarity index 97% rename from tests/witness/xml/customLevel.2 rename to tests/witness/customLevel.2 index bdf641d96d..fc957b2f60 100644 --- a/tests/witness/xml/customLevel.2 +++ b/tests/witness/customLevel.2 @@ -1,5 +1,5 @@ -DEBUG xml.CustomLevelTestCase - Message 1 -INFO xml.CustomLevelTestCase - Message 2 -WARN xml.CustomLevelTestCase - Message 3 -ERROR xml.CustomLevelTestCase - Message 4 -TRACE xml.CustomLevelTestCase - Message 5 +DEBUG xml.CustomLevelTestCase - Message 1 +INFO xml.CustomLevelTestCase - Message 2 +WARN xml.CustomLevelTestCase - Message 3 +ERROR xml.CustomLevelTestCase - Message 4 +TRACE xml.CustomLevelTestCase - Message 5 diff --git a/tests/witness/xml/customLevel.3 b/tests/witness/customLevel.3 similarity index 97% rename from tests/witness/xml/customLevel.3 rename to tests/witness/customLevel.3 index c25b5466c6..00a2986053 100644 --- a/tests/witness/xml/customLevel.3 +++ b/tests/witness/customLevel.3 @@ -1 +1 @@ -TRACE xml.CustomLevelTestCase - Message 5 +TRACE xml.CustomLevelTestCase - Message 5 diff --git a/tests/witness/xml/customLevel.4 b/tests/witness/customLevel.4 similarity index 97% rename from tests/witness/xml/customLevel.4 rename to tests/witness/customLevel.4 index bdf641d96d..fc957b2f60 100644 --- a/tests/witness/xml/customLevel.4 +++ b/tests/witness/customLevel.4 @@ -1,5 +1,5 @@ -DEBUG xml.CustomLevelTestCase - Message 1 -INFO xml.CustomLevelTestCase - Message 2 -WARN xml.CustomLevelTestCase - Message 3 -ERROR xml.CustomLevelTestCase - Message 4 -TRACE xml.CustomLevelTestCase - Message 5 +DEBUG xml.CustomLevelTestCase - Message 1 +INFO xml.CustomLevelTestCase - Message 2 +WARN xml.CustomLevelTestCase - Message 3 +ERROR xml.CustomLevelTestCase - Message 4 +TRACE xml.CustomLevelTestCase - Message 5 diff --git a/tests/witness/customLogger.1 b/tests/witness/customLogger.1 new file mode 100644 index 0000000000..5697b70dea --- /dev/null +++ b/tests/witness/customLogger.1 @@ -0,0 +1,17 @@ +TRACE customLogger.XLoggerTestCase - Message 0 +DEBUG customLogger.XLoggerTestCase - Message 1 +WARN customLogger.XLoggerTestCase - Message 2 +ERROR customLogger.XLoggerTestCase - Message 3 +FATAL customLogger.XLoggerTestCase - Message 4 +DEBUG customLogger.XLoggerTestCase - Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.customLogger.XLoggerTestCase.common(XLoggerTestCase.java:XXX) + at org.apache.log4j.customLogger.XLoggerTestCase.test1(XLoggerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/xml/customLogger.2 b/tests/witness/customLogger.2 similarity index 97% rename from tests/witness/xml/customLogger.2 rename to tests/witness/customLogger.2 index d344f45650..5990833212 100644 --- a/tests/witness/xml/customLogger.2 +++ b/tests/witness/customLogger.2 @@ -1 +1 @@ -TRACE customLogger.XLoggerTestCase - Message 0 +TRACE customLogger.XLoggerTestCase - Message 0 diff --git a/tests/witness/dom.A1.1 b/tests/witness/dom.A1.1 new file mode 100644 index 0000000000..0c619b6a1a --- /dev/null +++ b/tests/witness/dom.A1.1 @@ -0,0 +1,90 @@ +TRACE xml.DOMTestCase - Message 0 +TRACE xml.DOMTestCase - Message 0 +TRACE root - Message 0 +DEBUG xml.DOMTestCase - Message 1 +DEBUG xml.DOMTestCase - Message 1 +DEBUG root - Message 1 +INFO xml.DOMTestCase - Message 2 +INFO xml.DOMTestCase - Message 2 +INFO root - Message 2 +WARN xml.DOMTestCase - Message 3 +WARN xml.DOMTestCase - Message 3 +WARN root - Message 3 +ERROR xml.DOMTestCase - Message 4 +ERROR xml.DOMTestCase - Message 4 +ERROR root - Message 4 +FATAL xml.DOMTestCase - Message 5 +FATAL xml.DOMTestCase - Message 5 +FATAL root - Message 5 +DEBUG xml.DOMTestCase - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test1(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +DEBUG xml.DOMTestCase - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test1(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +DEBUG root - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test1(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +ERROR xml.DOMTestCase - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test1(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +ERROR xml.DOMTestCase - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test1(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +ERROR root - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test1(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/dom.A1.4 b/tests/witness/dom.A1.4 new file mode 100644 index 0000000000..5e961105d4 --- /dev/null +++ b/tests/witness/dom.A1.4 @@ -0,0 +1,90 @@ +TRACE xml.DOMTestCase - Message 0 +TRACE xml.DOMTestCase - Message 0 +TRACE root - Message 0 +DEBUG xml.DOMTestCase - Message 1 +DEBUG xml.DOMTestCase - Message 1 +DEBUG root - Message 1 +INFO xml.DOMTestCase - Message 2 +INFO xml.DOMTestCase - Message 2 +INFO root - Message 2 +WARN xml.DOMTestCase - Message 3 +WARN xml.DOMTestCase - Message 3 +WARN root - Message 3 +ERROR xml.DOMTestCase - Message 4 +ERROR xml.DOMTestCase - Message 4 +ERROR root - Message 4 +FATAL xml.DOMTestCase - Message 5 +FATAL xml.DOMTestCase - Message 5 +FATAL root - Message 5 +DEBUG xml.DOMTestCase - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test4(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +DEBUG xml.DOMTestCase - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test4(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +DEBUG root - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test4(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +ERROR xml.DOMTestCase - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test4(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +ERROR xml.DOMTestCase - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test4(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +ERROR root - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test4(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/dom.A2.1 b/tests/witness/dom.A2.1 new file mode 100644 index 0000000000..e04b617d85 --- /dev/null +++ b/tests/witness/dom.A2.1 @@ -0,0 +1,60 @@ + [main] TRACE org.apache.log4j.xml.DOMTestCase - Message 0 + [main] TRACE root - Message 0 + [main] DEBUG org.apache.log4j.xml.DOMTestCase - Message 1 + [main] DEBUG root - Message 1 + [main] INFO org.apache.log4j.xml.DOMTestCase - Message 2 + [main] INFO root - Message 2 + [main] WARN org.apache.log4j.xml.DOMTestCase - Message 3 + [main] WARN root - Message 3 + [main] ERROR org.apache.log4j.xml.DOMTestCase - Message 4 + [main] ERROR root - Message 4 + [main] FATAL org.apache.log4j.xml.DOMTestCase - Message 5 + [main] FATAL root - Message 5 + [main] DEBUG org.apache.log4j.xml.DOMTestCase - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test1(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] DEBUG root - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test1(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] ERROR org.apache.log4j.xml.DOMTestCase - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test1(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] ERROR root - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test1(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/dom.A2.4 b/tests/witness/dom.A2.4 new file mode 100644 index 0000000000..6444feeeb7 --- /dev/null +++ b/tests/witness/dom.A2.4 @@ -0,0 +1,60 @@ + [main] TRACE org.apache.log4j.xml.DOMTestCase - Message 0 + [main] TRACE root - Message 0 + [main] DEBUG org.apache.log4j.xml.DOMTestCase - Message 1 + [main] DEBUG root - Message 1 + [main] INFO org.apache.log4j.xml.DOMTestCase - Message 2 + [main] INFO root - Message 2 + [main] WARN org.apache.log4j.xml.DOMTestCase - Message 3 + [main] WARN root - Message 3 + [main] ERROR org.apache.log4j.xml.DOMTestCase - Message 4 + [main] ERROR root - Message 4 + [main] FATAL org.apache.log4j.xml.DOMTestCase - Message 5 + [main] FATAL root - Message 5 + [main] DEBUG org.apache.log4j.xml.DOMTestCase - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test4(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] DEBUG root - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test4(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] ERROR org.apache.log4j.xml.DOMTestCase - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test4(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] ERROR root - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.xml.DOMTestCase.common(DOMTestCase.java:XXX) + at org.apache.log4j.xml.DOMTestCase.test4(DOMTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/drfa_blockedRollover.log b/tests/witness/drfa_blockedRollover.log new file mode 100644 index 0000000000..3c7883740e --- /dev/null +++ b/tests/witness/drfa_blockedRollover.log @@ -0,0 +1,3 @@ +INFO - Prior to rollover +INFO - Rollover attempt while blocked +INFO - Message after block removed diff --git a/tests/witness/encoding/UTF-16.log b/tests/witness/encoding/UTF-16.log deleted file mode 100644 index 42469f8056..0000000000 Binary files a/tests/witness/encoding/UTF-16.log and /dev/null differ diff --git a/tests/witness/encoding/UTF-16BE.log b/tests/witness/encoding/UTF-16BE.log deleted file mode 100644 index ee13f10acf..0000000000 Binary files a/tests/witness/encoding/UTF-16BE.log and /dev/null differ diff --git a/tests/witness/encoding/UTF-16LE.log b/tests/witness/encoding/UTF-16LE.log deleted file mode 100644 index c6bdafc838..0000000000 Binary files a/tests/witness/encoding/UTF-16LE.log and /dev/null differ diff --git a/tests/witness/encoding/UTF-8.log b/tests/witness/encoding/UTF-8.log deleted file mode 100644 index acb46979d1..0000000000 --- a/tests/witness/encoding/UTF-8.log +++ /dev/null @@ -1,3 +0,0 @@ -INFO - Hello, World -INFO - ¹ -INFO - A؅԰আ七Ѐ diff --git a/tests/witness/encoding/ascii.log b/tests/witness/encoding/ascii.log deleted file mode 100644 index ef76502ad5..0000000000 --- a/tests/witness/encoding/ascii.log +++ /dev/null @@ -1,3 +0,0 @@ -INFO - Hello, World -INFO - ? -INFO - A????? diff --git a/tests/witness/encoding/latin1.log b/tests/witness/encoding/latin1.log deleted file mode 100644 index 7bd009888f..0000000000 --- a/tests/witness/encoding/latin1.log +++ /dev/null @@ -1,3 +0,0 @@ -INFO - Hello, World -INFO - ¹ -INFO - A????? diff --git a/tests/witness/fallback b/tests/witness/fallback deleted file mode 100644 index 62d43d54e3..0000000000 --- a/tests/witness/fallback +++ /dev/null @@ -1,62 +0,0 @@ -FALLBACK - test - Message 0 -FALLBACK - root - Message 0 -FALLBACK - test - Message 1 -FALLBACK - root - Message 1 -FALLBACK - test - Message 2 -FALLBACK - root - Message 2 -FALLBACK - test - Message 3 -FALLBACK - root - Message 3 -FALLBACK - test - Message 4 -FALLBACK - root - Message 4 -FALLBACK - test - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.varia.ErrorHandlerTestCase.common(X) - at org.apache.log4j.varia.ErrorHandlerTestCase.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -FALLBACK - root - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.varia.ErrorHandlerTestCase.common(X) - at org.apache.log4j.varia.ErrorHandlerTestCase.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -FALLBACK - test - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.varia.ErrorHandlerTestCase.common(X) - at org.apache.log4j.varia.ErrorHandlerTestCase.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -FALLBACK - root - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.varia.ErrorHandlerTestCase.common(X) - at org.apache.log4j.varia.ErrorHandlerTestCase.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/fallback1 b/tests/witness/fallback1 new file mode 100644 index 0000000000..21304513a6 --- /dev/null +++ b/tests/witness/fallback1 @@ -0,0 +1,58 @@ +FALLBACK - test - Message 0 +FALLBACK - root - Message 0 +FALLBACK - test - Message 1 +FALLBACK - root - Message 1 +FALLBACK - test - Message 2 +FALLBACK - root - Message 2 +FALLBACK - test - Message 3 +FALLBACK - root - Message 3 +FALLBACK - test - Message 4 +FALLBACK - root - Message 4 +FALLBACK - test - Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.varia.ErrorHandlerTestCase.common(ErrorHandlerTestCase.java:XXX) + at org.apache.log4j.varia.ErrorHandlerTestCase.test1(ErrorHandlerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +FALLBACK - root - Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.varia.ErrorHandlerTestCase.common(ErrorHandlerTestCase.java:XXX) + at org.apache.log4j.varia.ErrorHandlerTestCase.test1(ErrorHandlerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +FALLBACK - test - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.varia.ErrorHandlerTestCase.common(ErrorHandlerTestCase.java:XXX) + at org.apache.log4j.varia.ErrorHandlerTestCase.test1(ErrorHandlerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +FALLBACK - root - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.varia.ErrorHandlerTestCase.common(ErrorHandlerTestCase.java:XXX) + at org.apache.log4j.varia.ErrorHandlerTestCase.test1(ErrorHandlerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/filter/simpleFilter.1 b/tests/witness/filter/simpleFilter.1 deleted file mode 100644 index a63c4bf651..0000000000 --- a/tests/witness/filter/simpleFilter.1 +++ /dev/null @@ -1,4 +0,0 @@ -INFO - Message 1 -INFO - Message 1 -WARN - Message 2 -WARN - Message 2 diff --git a/tests/witness/filter/simpleFilter.11 b/tests/witness/filter/simpleFilter.11 deleted file mode 100644 index 87d060959b..0000000000 --- a/tests/witness/filter/simpleFilter.11 +++ /dev/null @@ -1,60 +0,0 @@ -DEBUG - Message 0 -DEBUG - Message 0 -INFO - Message 1 -INFO - Message 1 -ERROR - Message 3 -ERROR - Message 3 -FATAL - Message 4 -FATAL - Message 4 -DEBUG - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.filter.SimpleFilterTest.common(X) - at org.apache.log4j.filter.SimpleFilterTest.test11(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -DEBUG - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.filter.SimpleFilterTest.common(X) - at org.apache.log4j.filter.SimpleFilterTest.test11(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.filter.SimpleFilterTest.common(X) - at org.apache.log4j.filter.SimpleFilterTest.test11(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.filter.SimpleFilterTest.common(X) - at org.apache.log4j.filter.SimpleFilterTest.test11(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/filter/simpleFilter.6 b/tests/witness/filter/simpleFilter.6 deleted file mode 100644 index fb889b33c9..0000000000 --- a/tests/witness/filter/simpleFilter.6 +++ /dev/null @@ -1,2 +0,0 @@ -WARN - Message 2 -WARN - Message 2 diff --git a/tests/witness/filter/simpleFilter.7 b/tests/witness/filter/simpleFilter.7 deleted file mode 100644 index cbff806f40..0000000000 --- a/tests/witness/filter/simpleFilter.7 +++ /dev/null @@ -1,60 +0,0 @@ -DEBUG - Message 0 -DEBUG - Message 0 -INFO - Message 1 -INFO - Message 1 -ERROR - Message 3 -ERROR - Message 3 -FATAL - Message 4 -FATAL - Message 4 -DEBUG - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.filter.SimpleFilterTest.common(X) - at org.apache.log4j.filter.SimpleFilterTest.test7(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -DEBUG - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.filter.SimpleFilterTest.common(X) - at org.apache.log4j.filter.SimpleFilterTest.test7(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.filter.SimpleFilterTest.common(X) - at org.apache.log4j.filter.SimpleFilterTest.test7(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.filter.SimpleFilterTest.common(X) - at org.apache.log4j.filter.SimpleFilterTest.test7(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/filter/simpleFilter.8 b/tests/witness/filter/simpleFilter.8 deleted file mode 100644 index cad4163202..0000000000 --- a/tests/witness/filter/simpleFilter.8 +++ /dev/null @@ -1 +0,0 @@ -WARN org.apache.log4j.filter.SimpleFilterTest - Message 2 diff --git a/tests/witness/hierarchy/hierarchyThreshold.1 b/tests/witness/hierarchyThreshold.1 similarity index 100% rename from tests/witness/hierarchy/hierarchyThreshold.1 rename to tests/witness/hierarchyThreshold.1 diff --git a/tests/witness/hierarchy/hierarchyThreshold.2 b/tests/witness/hierarchyThreshold.2 similarity index 98% rename from tests/witness/hierarchy/hierarchyThreshold.2 rename to tests/witness/hierarchyThreshold.2 index 020576bd1c..a52c745116 100644 --- a/tests/witness/hierarchy/hierarchyThreshold.2 +++ b/tests/witness/hierarchyThreshold.2 @@ -1 +1 @@ -FATAL [main] log4j.HierarchyThresholdTestCase = m5 +FATAL [main] log4j.HierarchyThresholdTestCase = m5 diff --git a/tests/witness/hierarchy/hierarchyThreshold.3 b/tests/witness/hierarchyThreshold.3 similarity index 98% rename from tests/witness/hierarchy/hierarchyThreshold.3 rename to tests/witness/hierarchyThreshold.3 index 7e20229be4..1061b9a039 100644 --- a/tests/witness/hierarchy/hierarchyThreshold.3 +++ b/tests/witness/hierarchyThreshold.3 @@ -1,2 +1,2 @@ -ERROR [main] log4j.HierarchyThresholdTestCase = m4 -FATAL [main] log4j.HierarchyThresholdTestCase = m5 +ERROR [main] log4j.HierarchyThresholdTestCase = m4 +FATAL [main] log4j.HierarchyThresholdTestCase = m5 diff --git a/tests/witness/hierarchy/hierarchyThreshold.4 b/tests/witness/hierarchyThreshold.4 similarity index 98% rename from tests/witness/hierarchy/hierarchyThreshold.4 rename to tests/witness/hierarchyThreshold.4 index a179286e52..38ab9b3f97 100644 --- a/tests/witness/hierarchy/hierarchyThreshold.4 +++ b/tests/witness/hierarchyThreshold.4 @@ -1,3 +1,3 @@ -WARN [main] log4j.HierarchyThresholdTestCase = m3 -ERROR [main] log4j.HierarchyThresholdTestCase = m4 -FATAL [main] log4j.HierarchyThresholdTestCase = m5 +WARN [main] log4j.HierarchyThresholdTestCase = m3 +ERROR [main] log4j.HierarchyThresholdTestCase = m4 +FATAL [main] log4j.HierarchyThresholdTestCase = m5 diff --git a/tests/witness/hierarchy/hierarchyThreshold.5 b/tests/witness/hierarchyThreshold.5 similarity index 98% rename from tests/witness/hierarchy/hierarchyThreshold.5 rename to tests/witness/hierarchyThreshold.5 index 683eff1b0d..08591d98d9 100644 --- a/tests/witness/hierarchy/hierarchyThreshold.5 +++ b/tests/witness/hierarchyThreshold.5 @@ -1,4 +1,4 @@ -INFO [main] log4j.HierarchyThresholdTestCase = m2 -WARN [main] log4j.HierarchyThresholdTestCase = m3 -ERROR [main] log4j.HierarchyThresholdTestCase = m4 -FATAL [main] log4j.HierarchyThresholdTestCase = m5 +INFO [main] log4j.HierarchyThresholdTestCase = m2 +WARN [main] log4j.HierarchyThresholdTestCase = m3 +ERROR [main] log4j.HierarchyThresholdTestCase = m4 +FATAL [main] log4j.HierarchyThresholdTestCase = m5 diff --git a/tests/witness/hierarchy/hierarchyThreshold.6 b/tests/witness/hierarchyThreshold.6 similarity index 98% rename from tests/witness/hierarchy/hierarchyThreshold.6 rename to tests/witness/hierarchyThreshold.6 index 7a0bf09e0f..dfe5288306 100644 --- a/tests/witness/hierarchy/hierarchyThreshold.6 +++ b/tests/witness/hierarchyThreshold.6 @@ -1,5 +1,5 @@ -DEBUG [main] log4j.HierarchyThresholdTestCase = m1 -INFO [main] log4j.HierarchyThresholdTestCase = m2 -WARN [main] log4j.HierarchyThresholdTestCase = m3 -ERROR [main] log4j.HierarchyThresholdTestCase = m4 -FATAL [main] log4j.HierarchyThresholdTestCase = m5 +DEBUG [main] log4j.HierarchyThresholdTestCase = m1 +INFO [main] log4j.HierarchyThresholdTestCase = m2 +WARN [main] log4j.HierarchyThresholdTestCase = m3 +ERROR [main] log4j.HierarchyThresholdTestCase = m4 +FATAL [main] log4j.HierarchyThresholdTestCase = m5 diff --git a/tests/witness/hierarchy/hierarchyThreshold.7 b/tests/witness/hierarchyThreshold.7 similarity index 98% rename from tests/witness/hierarchy/hierarchyThreshold.7 rename to tests/witness/hierarchyThreshold.7 index 1047360330..095bb974c3 100644 --- a/tests/witness/hierarchy/hierarchyThreshold.7 +++ b/tests/witness/hierarchyThreshold.7 @@ -1,6 +1,6 @@ -TRACE [main] log4j.HierarchyThresholdTestCase = m0 -DEBUG [main] log4j.HierarchyThresholdTestCase = m1 -INFO [main] log4j.HierarchyThresholdTestCase = m2 -WARN [main] log4j.HierarchyThresholdTestCase = m3 -ERROR [main] log4j.HierarchyThresholdTestCase = m4 -FATAL [main] log4j.HierarchyThresholdTestCase = m5 +TRACE [main] log4j.HierarchyThresholdTestCase = m0 +DEBUG [main] log4j.HierarchyThresholdTestCase = m1 +INFO [main] log4j.HierarchyThresholdTestCase = m2 +WARN [main] log4j.HierarchyThresholdTestCase = m3 +ERROR [main] log4j.HierarchyThresholdTestCase = m4 +FATAL [main] log4j.HierarchyThresholdTestCase = m5 diff --git a/tests/witness/hierarchy/hierarchyThreshold.8 b/tests/witness/hierarchyThreshold.8 similarity index 98% rename from tests/witness/hierarchy/hierarchyThreshold.8 rename to tests/witness/hierarchyThreshold.8 index 1047360330..095bb974c3 100644 --- a/tests/witness/hierarchy/hierarchyThreshold.8 +++ b/tests/witness/hierarchyThreshold.8 @@ -1,6 +1,6 @@ -TRACE [main] log4j.HierarchyThresholdTestCase = m0 -DEBUG [main] log4j.HierarchyThresholdTestCase = m1 -INFO [main] log4j.HierarchyThresholdTestCase = m2 -WARN [main] log4j.HierarchyThresholdTestCase = m3 -ERROR [main] log4j.HierarchyThresholdTestCase = m4 -FATAL [main] log4j.HierarchyThresholdTestCase = m5 +TRACE [main] log4j.HierarchyThresholdTestCase = m0 +DEBUG [main] log4j.HierarchyThresholdTestCase = m1 +INFO [main] log4j.HierarchyThresholdTestCase = m2 +WARN [main] log4j.HierarchyThresholdTestCase = m3 +ERROR [main] log4j.HierarchyThresholdTestCase = m4 +FATAL [main] log4j.HierarchyThresholdTestCase = m5 diff --git a/tests/witness/joran/async b/tests/witness/joran/async deleted file mode 100644 index 4dd236d740..0000000000 --- a/tests/witness/joran/async +++ /dev/null @@ -1,62 +0,0 @@ -DEBUG - Message 0 -DEBUG - Message 0 -INFO - Message 1 -INFO - Message 1 -WARN - Message 2 -WARN - Message 2 -ERROR - Message 3 -ERROR - Message 3 -FATAL - Message 4 -FATAL - Message 4 -DEBUG - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.joran.JoranConfiguratorTest.common(X) - at org.apache.log4j.joran.JoranConfiguratorTest.testAsync(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -DEBUG - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.joran.JoranConfiguratorTest.common(X) - at org.apache.log4j.joran.JoranConfiguratorTest.testAsync(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.joran.JoranConfiguratorTest.common(X) - at org.apache.log4j.joran.JoranConfiguratorTest.testAsync(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.joran.JoranConfiguratorTest.common(X) - at org.apache.log4j.joran.JoranConfiguratorTest.testAsync(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/multiplex/multiplex-test1_bob.txt b/tests/witness/multiplex/multiplex-test1_bob.txt deleted file mode 100644 index bd0b856a1a..0000000000 --- a/tests/witness/multiplex/multiplex-test1_bob.txt +++ /dev/null @@ -1,2 +0,0 @@ -Hello Bob -I wonder what Jane's file looks like \ No newline at end of file diff --git a/tests/witness/multiplex/multiplex-test1_jane.txt b/tests/witness/multiplex/multiplex-test1_jane.txt deleted file mode 100644 index d4d358cded..0000000000 --- a/tests/witness/multiplex/multiplex-test1_jane.txt +++ /dev/null @@ -1,2 +0,0 @@ -Hello Jane -Bob. Be quiet. \ No newline at end of file diff --git a/tests/witness/ndc/NDC.1 b/tests/witness/ndc/NDC.1 deleted file mode 100644 index 239b8d0b6f..0000000000 --- a/tests/witness/ndc/NDC.1 +++ /dev/null @@ -1,25 +0,0 @@ -DEBUG null - m1 -INFO null - m2 -WARN null - m3 -ERROR null - m4 -FATAL null - m5 -DEBUG n1 - m1 -INFO n1 - m2 -WARN n1 - m3 -ERROR n1 - m4 -FATAL n1 - m5 -DEBUG n1 n2 n3 - m1 -INFO n1 n2 n3 - m2 -WARN n1 n2 n3 - m3 -ERROR n1 n2 n3 - m4 -FATAL n1 n2 n3 - m5 -DEBUG n1 n2 - m1 -INFO n1 n2 - m2 -WARN n1 n2 - m3 -ERROR n1 n2 - m4 -FATAL n1 n2 - m5 -DEBUG null - m1 -INFO null - m2 -WARN null - m3 -ERROR null - m4 -FATAL null - m5 diff --git a/tests/witness/net/socketServer.1 b/tests/witness/net/socketServer.1 deleted file mode 100644 index 996f673e13..0000000000 --- a/tests/witness/net/socketServer.1 +++ /dev/null @@ -1,31 +0,0 @@ -DEBUG T1 [main] org.apache.log4j.net.SocketServerTestCase Message 1 -DEBUG T1 [main] root Message 2 - INFO T1 [main] org.apache.log4j.net.SocketServerTestCase Message 3 - WARN T1 [main] org.apache.log4j.net.SocketServerTestCase Message 4 -LETHAL T1 [main] org.apache.log4j.net.SocketServerTestCase Message 5 -DEBUG T1 [main] org.apache.log4j.net.SocketServerTestCase Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.net.SocketServerTestCase.common(X) - at org.apache.log4j.net.SocketServerTestCase.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR T1 [main] root Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.net.SocketServerTestCase.common(X) - at org.apache.log4j.net.SocketServerTestCase.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) \ No newline at end of file diff --git a/tests/witness/net/socketServer.2 b/tests/witness/net/socketServer.2 deleted file mode 100644 index 52c9776beb..0000000000 --- a/tests/witness/net/socketServer.2 +++ /dev/null @@ -1,31 +0,0 @@ -DEBUG T2 [main] ? (?:?) Message 1 -DEBUG T2 [main] ? (?:?) Message 2 - INFO T2 [main] ? (?:?) Message 3 - WARN T2 [main] ? (?:?) Message 4 -LETHAL T2 [main] ? (?:?) Message 5 -DEBUG T2 [main] ? (?:?) Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.net.SocketServerTestCase.common(X) - at org.apache.log4j.net.SocketServerTestCase.test2(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR T2 [main] ? (?:?) Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.net.SocketServerTestCase.common(X) - at org.apache.log4j.net.SocketServerTestCase.test2(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) \ No newline at end of file diff --git a/tests/witness/net/socketServer.3 b/tests/witness/net/socketServer.3 deleted file mode 100644 index fa87a23a2c..0000000000 --- a/tests/witness/net/socketServer.3 +++ /dev/null @@ -1,31 +0,0 @@ -DEBUG T3 [main] org.apache.log4j.net.SocketServerTestCase (X) Message 1 -DEBUG T3 [main] org.apache.log4j.net.SocketServerTestCase (X) Message 2 - INFO T3 [main] org.apache.log4j.net.SocketServerTestCase (X) Message 3 - WARN T3 [main] org.apache.log4j.net.SocketServerTestCase (X) Message 4 -LETHAL T3 [main] org.apache.log4j.net.SocketServerTestCase (X) Message 5 -DEBUG T3 [main] org.apache.log4j.net.SocketServerTestCase (X) Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.net.SocketServerTestCase.common(X) - at org.apache.log4j.net.SocketServerTestCase.test3(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR T3 [main] org.apache.log4j.net.SocketServerTestCase (X) Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.net.SocketServerTestCase.common(X) - at org.apache.log4j.net.SocketServerTestCase.test3(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/net/socketServer.4 b/tests/witness/net/socketServer.4 deleted file mode 100644 index 32af7f4b4e..0000000000 --- a/tests/witness/net/socketServer.4 +++ /dev/null @@ -1,31 +0,0 @@ -DEBUG some T4 MDC-TEST4 [main] SocketServerTestCase - Message 1 -DEBUG some T4 MDC-TEST4 [main] root - Message 2 - INFO some T4 MDC-TEST4 [main] SocketServerTestCase - Message 3 - WARN some T4 MDC-TEST4 [main] SocketServerTestCase - Message 4 -LETHAL some T4 MDC-TEST4 [main] SocketServerTestCase - Message 5 -DEBUG some T4 MDC-TEST4 [main] SocketServerTestCase - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.net.SocketServerTestCase.common(X) - at org.apache.log4j.net.SocketServerTestCase.test4(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR some T4 MDC-TEST4 [main] root - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.net.SocketServerTestCase.common(X) - at org.apache.log4j.net.SocketServerTestCase.test4(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/net/socketServer.5 b/tests/witness/net/socketServer.5 deleted file mode 100644 index aa08f6f39d..0000000000 --- a/tests/witness/net/socketServer.5 +++ /dev/null @@ -1,31 +0,0 @@ -DEBUG some5 T5 MDC-TEST5 [main] SocketServerTestCase - Message 1 -DEBUG some5 T5 MDC-TEST5 [main] root - Message 2 - INFO some5 T5 MDC-TEST5 [main] SocketServerTestCase - Message 3 - WARN some5 T5 MDC-TEST5 [main] SocketServerTestCase - Message 4 -LETHAL some5 T5 MDC-TEST5 [main] SocketServerTestCase - Message 5 -DEBUG some5 T5 MDC-TEST5 [main] SocketServerTestCase - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.net.SocketServerTestCase.common(X) - at org.apache.log4j.net.SocketServerTestCase.test5(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR some5 T5 MDC-TEST5 [main] root - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.net.SocketServerTestCase.common(X) - at org.apache.log4j.net.SocketServerTestCase.test5(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/net/socketServer.6 b/tests/witness/net/socketServer.6 deleted file mode 100644 index 2ca8430a38..0000000000 --- a/tests/witness/net/socketServer.6 +++ /dev/null @@ -1,31 +0,0 @@ -DEBUG some6 T6 client-test6 MDC-TEST6 [main] SocketServerTestCase - Message 1 -DEBUG some6 T6 client-test6 MDC-TEST6 [main] root - Message 2 - INFO some6 T6 client-test6 MDC-TEST6 [main] SocketServerTestCase - Message 3 - WARN some6 T6 client-test6 MDC-TEST6 [main] SocketServerTestCase - Message 4 -LETHAL some6 T6 client-test6 MDC-TEST6 [main] SocketServerTestCase - Message 5 -DEBUG some6 T6 client-test6 MDC-TEST6 [main] SocketServerTestCase - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.net.SocketServerTestCase.common(X) - at org.apache.log4j.net.SocketServerTestCase.test6(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR some6 T6 client-test6 MDC-TEST6 [main] root - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.net.SocketServerTestCase.common(X) - at org.apache.log4j.net.SocketServerTestCase.test6(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/net/socketServer.7 b/tests/witness/net/socketServer.7 deleted file mode 100644 index b5b8b3ba25..0000000000 --- a/tests/witness/net/socketServer.7 +++ /dev/null @@ -1,31 +0,0 @@ -DEBUG some7 T7 client-test7 MDC-TEST7 [main] SocketServerTestCase - Message 1 -DEBUG some7 T7 client-test7 MDC-TEST7 [main] root - Message 2 - INFO some7 T7 client-test7 MDC-TEST7 [main] SocketServerTestCase - Message 3 - WARN some7 T7 client-test7 MDC-TEST7 [main] SocketServerTestCase - Message 4 -LETHAL some7 T7 client-test7 MDC-TEST7 [main] SocketServerTestCase - Message 5 -DEBUG some7 T7 client-test7 MDC-TEST7 [main] SocketServerTestCase - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.net.SocketServerTestCase.common(X) - at org.apache.log4j.net.SocketServerTestCase.test7(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR some7 T7 client-test7 MDC-TEST7 [main] root - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.net.SocketServerTestCase.common(X) - at org.apache.log4j.net.SocketServerTestCase.test7(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/net/socketServer.8 b/tests/witness/net/socketServer.8 deleted file mode 100644 index 0d6ea84b27..0000000000 --- a/tests/witness/net/socketServer.8 +++ /dev/null @@ -1,31 +0,0 @@ -DEBUG some8 T8 shortSocketServer MDC-TEST8 [main] SocketServerTestCase - Message 1 -DEBUG some8 T8 shortSocketServer MDC-TEST8 [main] root - Message 2 - INFO some8 T8 shortSocketServer MDC-TEST8 [main] SocketServerTestCase - Message 3 - WARN some8 T8 shortSocketServer MDC-TEST8 [main] SocketServerTestCase - Message 4 -LETHAL some8 T8 shortSocketServer MDC-TEST8 [main] SocketServerTestCase - Message 5 -DEBUG some8 T8 shortSocketServer MDC-TEST8 [main] SocketServerTestCase - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.net.SocketServerTestCase.common(X) - at org.apache.log4j.net.SocketServerTestCase.test8(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR some8 T8 shortSocketServer MDC-TEST8 [main] root - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.net.SocketServerTestCase.common(X) - at org.apache.log4j.net.SocketServerTestCase.test8(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/enhancedPatternLayout.1 b/tests/witness/pattern/enhancedPatternLayout.1 new file mode 100644 index 0000000000..d5ab5347c3 --- /dev/null +++ b/tests/witness/pattern/enhancedPatternLayout.1 @@ -0,0 +1,75 @@ +DEBUG - Message 0 +DEBUG - Message 0 +INFO - Message 1 +INFO - Message 1 +WARN - Message 2 +WARN - Message 2 +ERROR - Message 3 +ERROR - Message 3 +FATAL - Message 4 +FATAL - Message 4 +DEBUG - Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test1(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +INFO - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test1(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +WARN - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test1(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +ERROR - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test1(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +FATAL - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test1(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/enhancedPatternLayout.10 b/tests/witness/pattern/enhancedPatternLayout.10 new file mode 100644 index 0000000000..381c2db048 --- /dev/null +++ b/tests/witness/pattern/enhancedPatternLayout.10 @@ -0,0 +1,75 @@ +[main] DEBUG org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 0 +[main] DEBUG org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 0 +[main] INFO org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 1 +[main] INFO org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 1 +[main] WARN org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 2 +[main] WARN org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 2 +[main] ERROR org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 3 +[main] ERROR org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 3 +[main] FATAL org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 4 +[main] FATAL org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 4 +[main] DEBUG org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test10(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +[main] INFO org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test10(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +[main] WARN org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test10(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +[main] ERROR org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test10(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +[main] FATAL org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test10(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/enhancedPatternLayout.11 b/tests/witness/pattern/enhancedPatternLayout.11 new file mode 100644 index 0000000000..65f933b704 --- /dev/null +++ b/tests/witness/pattern/enhancedPatternLayout.11 @@ -0,0 +1,75 @@ +DEBUG [main] log4j.EnhancedPatternLayoutTest: Message 0 +DEBUG [main] root: Message 0 +INFO [main] log4j.EnhancedPatternLayoutTest: Message 1 +INFO [main] root: Message 1 +WARN [main] log4j.EnhancedPatternLayoutTest: Message 2 +WARN [main] root: Message 2 +ERROR [main] log4j.EnhancedPatternLayoutTest: Message 3 +ERROR [main] root: Message 3 +FATAL [main] log4j.EnhancedPatternLayoutTest: Message 4 +FATAL [main] root: Message 4 +DEBUG [main] log4j.EnhancedPatternLayoutTest: Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test11(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +INFO [main] log4j.EnhancedPatternLayoutTest: Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test11(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +WARN [main] log4j.EnhancedPatternLayoutTest: Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test11(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +ERROR [main] log4j.EnhancedPatternLayoutTest: Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test11(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +FATAL [main] log4j.EnhancedPatternLayoutTest: Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test11(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/enhancedPatternLayout.12 b/tests/witness/pattern/enhancedPatternLayout.12 new file mode 100644 index 0000000000..78039c7f03 --- /dev/null +++ b/tests/witness/pattern/enhancedPatternLayout.12 @@ -0,0 +1,75 @@ +[main] DEBUG org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 0 +[main] DEBUG org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 0 +[main] INFO org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 1 +[main] INFO org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 1 +[main] WARN org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 2 +[main] WARN org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 2 +[main] ERROR org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 3 +[main] ERROR org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 3 +[main] FATAL org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 4 +[main] FATAL org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 4 +[main] DEBUG org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test12(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +[main] INFO org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test12(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +[main] WARN org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test12(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +[main] ERROR org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test12(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +[main] FATAL org.apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test12(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/enhancedPatternLayout.13 b/tests/witness/pattern/enhancedPatternLayout.13 new file mode 100644 index 0000000000..dbd6bd4657 --- /dev/null +++ b/tests/witness/pattern/enhancedPatternLayout.13 @@ -0,0 +1,75 @@ +[main] DEBUG apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 0 +[main] DEBUG apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 0 +[main] INFO apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 1 +[main] INFO apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 1 +[main] WARN apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 2 +[main] WARN apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 2 +[main] ERROR apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 3 +[main] ERROR apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 3 +[main] FATAL apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 4 +[main] FATAL apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 4 +[main] DEBUG apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test13(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +[main] INFO apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test13(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +[main] WARN apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test13(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +[main] ERROR apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test13(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +[main] FATAL apache.log4j.EnhancedPatternLayoutTestCase.common(X): Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test13(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/enhancedPatternLayout.14 b/tests/witness/pattern/enhancedPatternLayout.14 new file mode 100644 index 0000000000..9bdc71ee2a --- /dev/null +++ b/tests/witness/pattern/enhancedPatternLayout.14 @@ -0,0 +1,75 @@ +DEBUG [main] o.a.l.EnhancedPatternLayoutTest: Message 0 +DEBUG [main] root: Message 0 +INFO [main] o.a.l.EnhancedPatternLayoutTest: Message 1 +INFO [main] root: Message 1 +WARN [main] o.a.l.EnhancedPatternLayoutTest: Message 2 +WARN [main] root: Message 2 +ERROR [main] o.a.l.EnhancedPatternLayoutTest: Message 3 +ERROR [main] root: Message 3 +FATAL [main] o.a.l.EnhancedPatternLayoutTest: Message 4 +FATAL [main] root: Message 4 +DEBUG [main] o.a.l.EnhancedPatternLayoutTest: Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test14(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +INFO [main] o.a.l.EnhancedPatternLayoutTest: Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test14(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +WARN [main] o.a.l.EnhancedPatternLayoutTest: Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test14(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +ERROR [main] o.a.l.EnhancedPatternLayoutTest: Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test14(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +FATAL [main] o.a.l.EnhancedPatternLayoutTest: Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test14(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/enhancedPatternLayout.15 b/tests/witness/pattern/enhancedPatternLayout.15 new file mode 100644 index 0000000000..7bf3de40fb --- /dev/null +++ b/tests/witness/pattern/enhancedPatternLayout.15 @@ -0,0 +1,75 @@ +DEBUG 1 - Message 0 +DEBUG 2 - Message 0 + INFO 3 - Message 1 + INFO 4 - Message 1 + WARN 5 - Message 2 + WARN 6 - Message 2 +ERROR 7 - Message 3 +ERROR 8 - Message 3 +FATAL 9 - Message 4 +FATAL 10 - Message 4 +DEBUG 11 - Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test15(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + INFO 12 - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test15(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + WARN 13 - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test15(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +ERROR 14 - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test15(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +FATAL 15 - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test15(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/enhancedPatternLayout.2 b/tests/witness/pattern/enhancedPatternLayout.2 new file mode 100644 index 0000000000..d4caecc625 --- /dev/null +++ b/tests/witness/pattern/enhancedPatternLayout.2 @@ -0,0 +1,75 @@ + [main] DEBUG atternLayoutTest - Message 0 + [main] DEBUG root - Message 0 + [main] INFO atternLayoutTest - Message 1 + [main] INFO root - Message 1 + [main] WARN atternLayoutTest - Message 2 + [main] WARN root - Message 2 + [main] ERROR atternLayoutTest - Message 3 + [main] ERROR root - Message 3 + [main] FATAL atternLayoutTest - Message 4 + [main] FATAL root - Message 4 + [main] DEBUG atternLayoutTest - Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test2(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] INFO atternLayoutTest - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test2(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] WARN atternLayoutTest - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test2(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] ERROR atternLayoutTest - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test2(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] FATAL atternLayoutTest - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test2(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/enhancedPatternLayout.3 b/tests/witness/pattern/enhancedPatternLayout.3 new file mode 100644 index 0000000000..248df6d60e --- /dev/null +++ b/tests/witness/pattern/enhancedPatternLayout.3 @@ -0,0 +1,75 @@ + [main] DEBUG atternLayoutTest - Message 0 + [main] DEBUG root - Message 0 + [main] INFO atternLayoutTest - Message 1 + [main] INFO root - Message 1 + [main] WARN atternLayoutTest - Message 2 + [main] WARN root - Message 2 + [main] ERROR atternLayoutTest - Message 3 + [main] ERROR root - Message 3 + [main] FATAL atternLayoutTest - Message 4 + [main] FATAL root - Message 4 + [main] DEBUG atternLayoutTest - Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test3(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] INFO atternLayoutTest - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test3(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] WARN atternLayoutTest - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test3(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] ERROR atternLayoutTest - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test3(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] FATAL atternLayoutTest - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test3(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/enhancedPatternLayout.4 b/tests/witness/pattern/enhancedPatternLayout.4 new file mode 100644 index 0000000000..4dce6ef4a5 --- /dev/null +++ b/tests/witness/pattern/enhancedPatternLayout.4 @@ -0,0 +1,75 @@ + [main] DEBUG atternLayoutTest - Message 0 + [main] DEBUG root - Message 0 + [main] INFO atternLayoutTest - Message 1 + [main] INFO root - Message 1 + [main] WARN atternLayoutTest - Message 2 + [main] WARN root - Message 2 + [main] ERROR atternLayoutTest - Message 3 + [main] ERROR root - Message 3 + [main] FATAL atternLayoutTest - Message 4 + [main] FATAL root - Message 4 + [main] DEBUG atternLayoutTest - Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test4(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] INFO atternLayoutTest - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test4(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] WARN atternLayoutTest - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test4(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] ERROR atternLayoutTest - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test4(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] FATAL atternLayoutTest - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test4(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/enhancedPatternLayout.5 b/tests/witness/pattern/enhancedPatternLayout.5 new file mode 100644 index 0000000000..cb88bddb6c --- /dev/null +++ b/tests/witness/pattern/enhancedPatternLayout.5 @@ -0,0 +1,75 @@ + [main] DEBUG atternLayoutTest - Message 0 + [main] DEBUG root - Message 0 + [main] INFO atternLayoutTest - Message 1 + [main] INFO root - Message 1 + [main] WARN atternLayoutTest - Message 2 + [main] WARN root - Message 2 + [main] ERROR atternLayoutTest - Message 3 + [main] ERROR root - Message 3 + [main] FATAL atternLayoutTest - Message 4 + [main] FATAL root - Message 4 + [main] DEBUG atternLayoutTest - Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test5(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] INFO atternLayoutTest - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test5(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] WARN atternLayoutTest - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test5(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] ERROR atternLayoutTest - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test5(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] FATAL atternLayoutTest - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test5(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/enhancedPatternLayout.6 b/tests/witness/pattern/enhancedPatternLayout.6 new file mode 100644 index 0000000000..5e1db41d5d --- /dev/null +++ b/tests/witness/pattern/enhancedPatternLayout.6 @@ -0,0 +1,75 @@ + [main] DEBUG atternLayoutTest - Message 0 + [main] DEBUG root - Message 0 + [main] INFO atternLayoutTest - Message 1 + [main] INFO root - Message 1 + [main] WARN atternLayoutTest - Message 2 + [main] WARN root - Message 2 + [main] ERROR atternLayoutTest - Message 3 + [main] ERROR root - Message 3 + [main] FATAL atternLayoutTest - Message 4 + [main] FATAL root - Message 4 + [main] DEBUG atternLayoutTest - Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test6(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] INFO atternLayoutTest - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test6(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] WARN atternLayoutTest - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test6(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] ERROR atternLayoutTest - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test6(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] FATAL atternLayoutTest - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test6(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/enhancedPatternLayout.7 b/tests/witness/pattern/enhancedPatternLayout.7 new file mode 100644 index 0000000000..5c6daa4572 --- /dev/null +++ b/tests/witness/pattern/enhancedPatternLayout.7 @@ -0,0 +1,75 @@ + [main] DEBUG atternLayoutTest - Message 0 + [main] DEBUG root - Message 0 + [main] INFO atternLayoutTest - Message 1 + [main] INFO root - Message 1 + [main] WARN atternLayoutTest - Message 2 + [main] WARN root - Message 2 + [main] ERROR atternLayoutTest - Message 3 + [main] ERROR root - Message 3 + [main] FATAL atternLayoutTest - Message 4 + [main] FATAL root - Message 4 + [main] DEBUG atternLayoutTest - Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test7(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] INFO atternLayoutTest - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test7(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] WARN atternLayoutTest - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test7(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] ERROR atternLayoutTest - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test7(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] FATAL atternLayoutTest - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test7(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/enhancedPatternLayout.8 b/tests/witness/pattern/enhancedPatternLayout.8 new file mode 100644 index 0000000000..2a08506812 --- /dev/null +++ b/tests/witness/pattern/enhancedPatternLayout.8 @@ -0,0 +1,75 @@ + [main] DEBUG atternLayoutTest - Message 0 + [main] DEBUG root - Message 0 + [main] INFO atternLayoutTest - Message 1 + [main] INFO root - Message 1 + [main] WARN atternLayoutTest - Message 2 + [main] WARN root - Message 2 + [main] ERROR atternLayoutTest - Message 3 + [main] ERROR root - Message 3 + [main] FATAL atternLayoutTest - Message 4 + [main] FATAL root - Message 4 + [main] DEBUG atternLayoutTest - Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test8(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] INFO atternLayoutTest - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test8(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] WARN atternLayoutTest - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test8(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] ERROR atternLayoutTest - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test8(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) + [main] FATAL atternLayoutTest - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test8(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/enhancedPatternLayout.9 b/tests/witness/pattern/enhancedPatternLayout.9 new file mode 100644 index 0000000000..6b8dd1af87 --- /dev/null +++ b/tests/witness/pattern/enhancedPatternLayout.9 @@ -0,0 +1,75 @@ +[main] DEBUG atternLayoutTest : Message 0 +[main] DEBUG root : Message 0 +[main] INFO atternLayoutTest : Message 1 +[main] INFO root : Message 1 +[main] WARN atternLayoutTest : Message 2 +[main] WARN root : Message 2 +[main] ERROR atternLayoutTest : Message 3 +[main] ERROR root : Message 3 +[main] FATAL atternLayoutTest : Message 4 +[main] FATAL root : Message 4 +[main] DEBUG atternLayoutTest : Message 5 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test9(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +[main] INFO atternLayoutTest : Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test9(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +[main] WARN atternLayoutTest : Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test9(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +[main] ERROR atternLayoutTest : Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test9(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +[main] FATAL atternLayoutTest : Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.EnhancedPatternLayoutTestCase.common(X) + at org.apache.log4j.EnhancedPatternLayoutTestCase.test9(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/patternLayout.mdc.1 b/tests/witness/pattern/enhancedPatternLayout.mdc.1 similarity index 100% rename from tests/witness/pattern/patternLayout.mdc.1 rename to tests/witness/pattern/enhancedPatternLayout.mdc.1 diff --git a/tests/witness/pattern/patternLayout.mdc.2 b/tests/witness/pattern/enhancedPatternLayout.mdc.2 similarity index 100% rename from tests/witness/pattern/patternLayout.mdc.2 rename to tests/witness/pattern/enhancedPatternLayout.mdc.2 diff --git a/tests/witness/pattern/enhancedPatternLayout.throwable b/tests/witness/pattern/enhancedPatternLayout.throwable new file mode 100644 index 0000000000..f191123779 --- /dev/null +++ b/tests/witness/pattern/enhancedPatternLayout.throwable @@ -0,0 +1,54 @@ +starting throwable pattern test +plain pattern, no exception +plain pattern, with exception +java.lang.Exception: Test Exception + at org.apache.log4j.EnhancedPatternLayoutTestCase.testThrowable(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +%throwable, no exception +%throwable, with exception +java.lang.Exception: Test Exception + at org.apache.log4j.EnhancedPatternLayoutTestCase.testThrowable(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +%throwable{short}, no exception +%throwable{short}, with exception +java.lang.Exception: Test Exception +%throwable{none}, no exception +%throwable{none}, with exception +%throwable{0}, no exception +%throwable{0}, with exception +%throwable{1}, no exception +%throwable{1}, with exception +java.lang.Exception: Test Exception +%throwable{100}, no exception +%throwable{100}, with exception +java.lang.Exception: Test Exception + at org.apache.log4j.EnhancedPatternLayoutTestCase.testThrowable(X) + at java.lang.reflect.Method.invoke(X) + at junit.framework.TestCase.runTest(X) + at junit.framework.TestCase.runBare(X) + at junit.framework.TestResult$1.protect(X) + at junit.framework.TestResult.runProtected(X) + at junit.framework.TestResult.run(X) + at junit.framework.TestCase.run(X) + at junit.framework.TestSuite.runTest(X) + at junit.framework.TestSuite.run(X) +%throwable{-n}, no exception +%throwable{-n}, with exception +java.lang.Exception: Test Exception + at org.apache.log4j.EnhancedPatternLayoutTestCase.testThrowable(X) diff --git a/tests/witness/pattern/patternLayout.1 b/tests/witness/pattern/patternLayout.1 deleted file mode 100644 index 4106965107..0000000000 --- a/tests/witness/pattern/patternLayout.1 +++ /dev/null @@ -1,75 +0,0 @@ -DEBUG - Message 0 -DEBUG - Message 0 -INFO - Message 1 -INFO - Message 1 -WARN - Message 2 -WARN - Message 2 -ERROR - Message 3 -ERROR - Message 3 -FATAL - Message 4 -FATAL - Message 4 -DEBUG - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -INFO - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -WARN - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -FATAL - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/patternLayout.10 b/tests/witness/pattern/patternLayout.10 deleted file mode 100644 index b86de54d7a..0000000000 --- a/tests/witness/pattern/patternLayout.10 +++ /dev/null @@ -1,75 +0,0 @@ -[main] DEBUG org.apache.log4j.PatternLayoutTestCase.common(X): Message 0 -[main] DEBUG org.apache.log4j.PatternLayoutTestCase.common(X): Message 0 -[main] INFO org.apache.log4j.PatternLayoutTestCase.common(X): Message 1 -[main] INFO org.apache.log4j.PatternLayoutTestCase.common(X): Message 1 -[main] WARN org.apache.log4j.PatternLayoutTestCase.common(X): Message 2 -[main] WARN org.apache.log4j.PatternLayoutTestCase.common(X): Message 2 -[main] ERROR org.apache.log4j.PatternLayoutTestCase.common(X): Message 3 -[main] ERROR org.apache.log4j.PatternLayoutTestCase.common(X): Message 3 -[main] FATAL org.apache.log4j.PatternLayoutTestCase.common(X): Message 4 -[main] FATAL org.apache.log4j.PatternLayoutTestCase.common(X): Message 4 -[main] DEBUG org.apache.log4j.PatternLayoutTestCase.common(X): Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test10(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -[main] INFO org.apache.log4j.PatternLayoutTestCase.common(X): Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test10(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -[main] WARN org.apache.log4j.PatternLayoutTestCase.common(X): Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test10(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -[main] ERROR org.apache.log4j.PatternLayoutTestCase.common(X): Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test10(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -[main] FATAL org.apache.log4j.PatternLayoutTestCase.common(X): Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test10(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/patternLayout.11 b/tests/witness/pattern/patternLayout.11 deleted file mode 100644 index d048044bb0..0000000000 --- a/tests/witness/pattern/patternLayout.11 +++ /dev/null @@ -1,75 +0,0 @@ -DEBUG [main] log4j.PatternLayoutTest: Message 0 -DEBUG [main] root: Message 0 -INFO [main] log4j.PatternLayoutTest: Message 1 -INFO [main] root: Message 1 -WARN [main] log4j.PatternLayoutTest: Message 2 -WARN [main] root: Message 2 -ERROR [main] log4j.PatternLayoutTest: Message 3 -ERROR [main] root: Message 3 -FATAL [main] log4j.PatternLayoutTest: Message 4 -FATAL [main] root: Message 4 -DEBUG [main] log4j.PatternLayoutTest: Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test11(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -INFO [main] log4j.PatternLayoutTest: Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test11(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -WARN [main] log4j.PatternLayoutTest: Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test11(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR [main] log4j.PatternLayoutTest: Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test11(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -FATAL [main] log4j.PatternLayoutTest: Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test11(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/patternLayout.12 b/tests/witness/pattern/patternLayout.12 deleted file mode 100644 index 5154d49f29..0000000000 --- a/tests/witness/pattern/patternLayout.12 +++ /dev/null @@ -1,75 +0,0 @@ -[main] DEBUG org.apache.log4j.PatternLayoutTestCase.common(X): Message 0 -[main] DEBUG org.apache.log4j.PatternLayoutTestCase.common(X): Message 0 -[main] INFO org.apache.log4j.PatternLayoutTestCase.common(X): Message 1 -[main] INFO org.apache.log4j.PatternLayoutTestCase.common(X): Message 1 -[main] WARN org.apache.log4j.PatternLayoutTestCase.common(X): Message 2 -[main] WARN org.apache.log4j.PatternLayoutTestCase.common(X): Message 2 -[main] ERROR org.apache.log4j.PatternLayoutTestCase.common(X): Message 3 -[main] ERROR org.apache.log4j.PatternLayoutTestCase.common(X): Message 3 -[main] FATAL org.apache.log4j.PatternLayoutTestCase.common(X): Message 4 -[main] FATAL org.apache.log4j.PatternLayoutTestCase.common(X): Message 4 -[main] DEBUG org.apache.log4j.PatternLayoutTestCase.common(X): Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test12(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -[main] INFO org.apache.log4j.PatternLayoutTestCase.common(X): Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test12(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -[main] WARN org.apache.log4j.PatternLayoutTestCase.common(X): Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test12(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -[main] ERROR org.apache.log4j.PatternLayoutTestCase.common(X): Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test12(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -[main] FATAL org.apache.log4j.PatternLayoutTestCase.common(X): Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test12(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/patternLayout.13 b/tests/witness/pattern/patternLayout.13 deleted file mode 100644 index eb32227b52..0000000000 --- a/tests/witness/pattern/patternLayout.13 +++ /dev/null @@ -1,75 +0,0 @@ -[main] DEBUG apache.log4j.PatternLayoutTestCase.common(X): Message 0 -[main] DEBUG apache.log4j.PatternLayoutTestCase.common(X): Message 0 -[main] INFO apache.log4j.PatternLayoutTestCase.common(X): Message 1 -[main] INFO apache.log4j.PatternLayoutTestCase.common(X): Message 1 -[main] WARN apache.log4j.PatternLayoutTestCase.common(X): Message 2 -[main] WARN apache.log4j.PatternLayoutTestCase.common(X): Message 2 -[main] ERROR apache.log4j.PatternLayoutTestCase.common(X): Message 3 -[main] ERROR apache.log4j.PatternLayoutTestCase.common(X): Message 3 -[main] FATAL apache.log4j.PatternLayoutTestCase.common(X): Message 4 -[main] FATAL apache.log4j.PatternLayoutTestCase.common(X): Message 4 -[main] DEBUG apache.log4j.PatternLayoutTestCase.common(X): Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test13(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -[main] INFO apache.log4j.PatternLayoutTestCase.common(X): Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test13(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -[main] WARN apache.log4j.PatternLayoutTestCase.common(X): Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test13(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -[main] ERROR apache.log4j.PatternLayoutTestCase.common(X): Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test13(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -[main] FATAL apache.log4j.PatternLayoutTestCase.common(X): Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test13(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/patternLayout.14 b/tests/witness/pattern/patternLayout.14 deleted file mode 100644 index 5fa192fe3b..0000000000 --- a/tests/witness/pattern/patternLayout.14 +++ /dev/null @@ -1,75 +0,0 @@ -DEBUG [main] o.a.l.PatternLayoutTest: Message 0 -DEBUG [main] root: Message 0 -INFO [main] o.a.l.PatternLayoutTest: Message 1 -INFO [main] root: Message 1 -WARN [main] o.a.l.PatternLayoutTest: Message 2 -WARN [main] root: Message 2 -ERROR [main] o.a.l.PatternLayoutTest: Message 3 -ERROR [main] root: Message 3 -FATAL [main] o.a.l.PatternLayoutTest: Message 4 -FATAL [main] root: Message 4 -DEBUG [main] o.a.l.PatternLayoutTest: Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test14(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -INFO [main] o.a.l.PatternLayoutTest: Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test14(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -WARN [main] o.a.l.PatternLayoutTest: Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test14(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR [main] o.a.l.PatternLayoutTest: Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test14(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -FATAL [main] o.a.l.PatternLayoutTest: Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test14(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/patternLayout.15 b/tests/witness/pattern/patternLayout.15 deleted file mode 100644 index 320b05fb81..0000000000 --- a/tests/witness/pattern/patternLayout.15 +++ /dev/null @@ -1,75 +0,0 @@ -DEBUG 1 - Message 0 -DEBUG 2 - Message 0 - INFO 3 - Message 1 - INFO 4 - Message 1 - WARN 5 - Message 2 - WARN 6 - Message 2 -ERROR 7 - Message 3 -ERROR 8 - Message 3 -FATAL 9 - Message 4 -FATAL 10 - Message 4 -DEBUG 11 - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test15(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - INFO 12 - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test15(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - WARN 13 - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test15(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR 14 - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test15(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -FATAL 15 - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test15(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/patternLayout.2 b/tests/witness/pattern/patternLayout.2 deleted file mode 100644 index 66eba39b31..0000000000 --- a/tests/witness/pattern/patternLayout.2 +++ /dev/null @@ -1,75 +0,0 @@ - [main] DEBUG atternLayoutTest - Message 0 - [main] DEBUG root - Message 0 - [main] INFO atternLayoutTest - Message 1 - [main] INFO root - Message 1 - [main] WARN atternLayoutTest - Message 2 - [main] WARN root - Message 2 - [main] ERROR atternLayoutTest - Message 3 - [main] ERROR root - Message 3 - [main] FATAL atternLayoutTest - Message 4 - [main] FATAL root - Message 4 - [main] DEBUG atternLayoutTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test2(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] INFO atternLayoutTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test2(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] WARN atternLayoutTest - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test2(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] ERROR atternLayoutTest - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test2(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] FATAL atternLayoutTest - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test2(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/patternLayout.3 b/tests/witness/pattern/patternLayout.3 deleted file mode 100644 index a3c4dfea01..0000000000 --- a/tests/witness/pattern/patternLayout.3 +++ /dev/null @@ -1,75 +0,0 @@ - [main] DEBUG atternLayoutTest - Message 0 - [main] DEBUG root - Message 0 - [main] INFO atternLayoutTest - Message 1 - [main] INFO root - Message 1 - [main] WARN atternLayoutTest - Message 2 - [main] WARN root - Message 2 - [main] ERROR atternLayoutTest - Message 3 - [main] ERROR root - Message 3 - [main] FATAL atternLayoutTest - Message 4 - [main] FATAL root - Message 4 - [main] DEBUG atternLayoutTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test3(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] INFO atternLayoutTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test3(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] WARN atternLayoutTest - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test3(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] ERROR atternLayoutTest - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test3(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] FATAL atternLayoutTest - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test3(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/patternLayout.4 b/tests/witness/pattern/patternLayout.4 deleted file mode 100644 index a65c71ecb5..0000000000 --- a/tests/witness/pattern/patternLayout.4 +++ /dev/null @@ -1,75 +0,0 @@ - [main] DEBUG atternLayoutTest - Message 0 - [main] DEBUG root - Message 0 - [main] INFO atternLayoutTest - Message 1 - [main] INFO root - Message 1 - [main] WARN atternLayoutTest - Message 2 - [main] WARN root - Message 2 - [main] ERROR atternLayoutTest - Message 3 - [main] ERROR root - Message 3 - [main] FATAL atternLayoutTest - Message 4 - [main] FATAL root - Message 4 - [main] DEBUG atternLayoutTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test4(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] INFO atternLayoutTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test4(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] WARN atternLayoutTest - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test4(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] ERROR atternLayoutTest - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test4(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] FATAL atternLayoutTest - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test4(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/patternLayout.5 b/tests/witness/pattern/patternLayout.5 deleted file mode 100644 index fd8338f569..0000000000 --- a/tests/witness/pattern/patternLayout.5 +++ /dev/null @@ -1,75 +0,0 @@ - [main] DEBUG atternLayoutTest - Message 0 - [main] DEBUG root - Message 0 - [main] INFO atternLayoutTest - Message 1 - [main] INFO root - Message 1 - [main] WARN atternLayoutTest - Message 2 - [main] WARN root - Message 2 - [main] ERROR atternLayoutTest - Message 3 - [main] ERROR root - Message 3 - [main] FATAL atternLayoutTest - Message 4 - [main] FATAL root - Message 4 - [main] DEBUG atternLayoutTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test5(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] INFO atternLayoutTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test5(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] WARN atternLayoutTest - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test5(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] ERROR atternLayoutTest - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test5(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] FATAL atternLayoutTest - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test5(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/patternLayout.6 b/tests/witness/pattern/patternLayout.6 deleted file mode 100644 index 9e4d14cc5a..0000000000 --- a/tests/witness/pattern/patternLayout.6 +++ /dev/null @@ -1,75 +0,0 @@ - [main] DEBUG atternLayoutTest - Message 0 - [main] DEBUG root - Message 0 - [main] INFO atternLayoutTest - Message 1 - [main] INFO root - Message 1 - [main] WARN atternLayoutTest - Message 2 - [main] WARN root - Message 2 - [main] ERROR atternLayoutTest - Message 3 - [main] ERROR root - Message 3 - [main] FATAL atternLayoutTest - Message 4 - [main] FATAL root - Message 4 - [main] DEBUG atternLayoutTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test6(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] INFO atternLayoutTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test6(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] WARN atternLayoutTest - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test6(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] ERROR atternLayoutTest - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test6(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] FATAL atternLayoutTest - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test6(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/patternLayout.7 b/tests/witness/pattern/patternLayout.7 deleted file mode 100644 index 4a1d8981c3..0000000000 --- a/tests/witness/pattern/patternLayout.7 +++ /dev/null @@ -1,75 +0,0 @@ - [main] DEBUG atternLayoutTest - Message 0 - [main] DEBUG root - Message 0 - [main] INFO atternLayoutTest - Message 1 - [main] INFO root - Message 1 - [main] WARN atternLayoutTest - Message 2 - [main] WARN root - Message 2 - [main] ERROR atternLayoutTest - Message 3 - [main] ERROR root - Message 3 - [main] FATAL atternLayoutTest - Message 4 - [main] FATAL root - Message 4 - [main] DEBUG atternLayoutTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test7(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] INFO atternLayoutTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test7(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] WARN atternLayoutTest - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test7(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] ERROR atternLayoutTest - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test7(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] FATAL atternLayoutTest - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test7(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/patternLayout.8 b/tests/witness/pattern/patternLayout.8 deleted file mode 100644 index 64906c697a..0000000000 --- a/tests/witness/pattern/patternLayout.8 +++ /dev/null @@ -1,75 +0,0 @@ - [main] DEBUG atternLayoutTest - Message 0 - [main] DEBUG root - Message 0 - [main] INFO atternLayoutTest - Message 1 - [main] INFO root - Message 1 - [main] WARN atternLayoutTest - Message 2 - [main] WARN root - Message 2 - [main] ERROR atternLayoutTest - Message 3 - [main] ERROR root - Message 3 - [main] FATAL atternLayoutTest - Message 4 - [main] FATAL root - Message 4 - [main] DEBUG atternLayoutTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test8(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] INFO atternLayoutTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test8(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] WARN atternLayoutTest - Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test8(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] ERROR atternLayoutTest - Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test8(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] FATAL atternLayoutTest - Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test8(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/pattern/patternLayout.9 b/tests/witness/pattern/patternLayout.9 deleted file mode 100644 index a6b3cfa4c4..0000000000 --- a/tests/witness/pattern/patternLayout.9 +++ /dev/null @@ -1,75 +0,0 @@ -[main] DEBUG atternLayoutTest : Message 0 -[main] DEBUG root : Message 0 -[main] INFO atternLayoutTest : Message 1 -[main] INFO root : Message 1 -[main] WARN atternLayoutTest : Message 2 -[main] WARN root : Message 2 -[main] ERROR atternLayoutTest : Message 3 -[main] ERROR root : Message 3 -[main] FATAL atternLayoutTest : Message 4 -[main] FATAL root : Message 4 -[main] DEBUG atternLayoutTest : Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test9(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -[main] INFO atternLayoutTest : Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test9(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -[main] WARN atternLayoutTest : Message 7 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test9(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -[main] ERROR atternLayoutTest : Message 8 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test9(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -[main] FATAL atternLayoutTest : Message 9 -java.lang.Exception: Just testing - at org.apache.log4j.PatternLayoutTestCase.common(X) - at org.apache.log4j.PatternLayoutTestCase.test9(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/patternLayout.1 b/tests/witness/patternLayout.1 new file mode 100644 index 0000000000..263f242977 --- /dev/null +++ b/tests/witness/patternLayout.1 @@ -0,0 +1,84 @@ +TRACE - Message 0 +TRACE - Message 0 +DEBUG - Message 1 +DEBUG - Message 1 +INFO - Message 2 +INFO - Message 2 +WARN - Message 3 +WARN - Message 3 +ERROR - Message 4 +ERROR - Message 4 +FATAL - Message 5 +FATAL - Message 5 +TRACE - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test1(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +DEBUG - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test1(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +INFO - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test1(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +WARN - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test1(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +ERROR - Message 10 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test1(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +FATAL - Message 11 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test1(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/patternLayout.10 b/tests/witness/patternLayout.10 new file mode 100644 index 0000000000..46fce63db2 --- /dev/null +++ b/tests/witness/patternLayout.10 @@ -0,0 +1,84 @@ +[main] TRACE org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 0 +[main] TRACE org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 0 +[main] DEBUG org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 1 +[main] DEBUG org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 1 +[main] INFO org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 2 +[main] INFO org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 2 +[main] WARN org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 3 +[main] WARN org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 3 +[main] ERROR org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 4 +[main] ERROR org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 4 +[main] FATAL org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 5 +[main] FATAL org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 5 +[main] TRACE org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test10(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] DEBUG org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test10(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] INFO org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test10(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] WARN org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test10(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] ERROR org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 10 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test10(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] FATAL org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 11 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test10(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/patternLayout.11 b/tests/witness/patternLayout.11 new file mode 100644 index 0000000000..6a91cc54d7 --- /dev/null +++ b/tests/witness/patternLayout.11 @@ -0,0 +1,84 @@ +TRACE [main] log4j.PatternLayoutTestCase: Message 0 +TRACE [main] root: Message 0 +DEBUG [main] log4j.PatternLayoutTestCase: Message 1 +DEBUG [main] root: Message 1 +INFO [main] log4j.PatternLayoutTestCase: Message 2 +INFO [main] root: Message 2 +WARN [main] log4j.PatternLayoutTestCase: Message 3 +WARN [main] root: Message 3 +ERROR [main] log4j.PatternLayoutTestCase: Message 4 +ERROR [main] root: Message 4 +FATAL [main] log4j.PatternLayoutTestCase: Message 5 +FATAL [main] root: Message 5 +TRACE [main] log4j.PatternLayoutTestCase: Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test11(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +DEBUG [main] log4j.PatternLayoutTestCase: Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test11(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +INFO [main] log4j.PatternLayoutTestCase: Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test11(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +WARN [main] log4j.PatternLayoutTestCase: Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test11(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +ERROR [main] log4j.PatternLayoutTestCase: Message 10 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test11(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +FATAL [main] log4j.PatternLayoutTestCase: Message 11 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test11(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/patternLayout.12 b/tests/witness/patternLayout.12 new file mode 100644 index 0000000000..374f54a6bf --- /dev/null +++ b/tests/witness/patternLayout.12 @@ -0,0 +1,84 @@ +[main] TRACE org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 0 +[main] TRACE org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 0 +[main] DEBUG org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 1 +[main] DEBUG org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 1 +[main] INFO org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 2 +[main] INFO org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 2 +[main] WARN org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 3 +[main] WARN org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 3 +[main] ERROR org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 4 +[main] ERROR org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 4 +[main] FATAL org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 5 +[main] FATAL org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 5 +[main] TRACE org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test12(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] DEBUG org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test12(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] INFO org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test12(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] WARN org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test12(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] ERROR org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 10 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test12(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] FATAL org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 11 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test12(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/patternLayout.13 b/tests/witness/patternLayout.13 new file mode 100644 index 0000000000..a359f35761 --- /dev/null +++ b/tests/witness/patternLayout.13 @@ -0,0 +1,84 @@ +[main] TRACE apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 0 +[main] TRACE apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 0 +[main] DEBUG apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 1 +[main] DEBUG apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 1 +[main] INFO apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 2 +[main] INFO apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 2 +[main] WARN apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 3 +[main] WARN apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 3 +[main] ERROR apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 4 +[main] ERROR apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 4 +[main] FATAL apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 5 +[main] FATAL apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 5 +[main] TRACE apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test13(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] DEBUG apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test13(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] INFO apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test13(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] WARN apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test13(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] ERROR apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 10 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test13(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] FATAL apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX): Message 11 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test13(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/patternLayout.14 b/tests/witness/patternLayout.14 new file mode 100644 index 0000000000..df0ebbdfa5 --- /dev/null +++ b/tests/witness/patternLayout.14 @@ -0,0 +1,84 @@ +TRACE 1 - Message 0 +TRACE 2 - Message 0 +DEBUG 3 - Message 1 +DEBUG 4 - Message 1 + INFO 5 - Message 2 + INFO 6 - Message 2 + WARN 7 - Message 3 + WARN 8 - Message 3 +ERROR 9 - Message 4 +ERROR 10 - Message 4 +FATAL 11 - Message 5 +FATAL 12 - Message 5 +TRACE 13 - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test14(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +DEBUG 14 - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test14(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + INFO 15 - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test14(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + WARN 16 - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test14(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +ERROR 17 - Message 10 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test14(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +FATAL 18 - Message 11 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test14(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/patternLayout.2 b/tests/witness/patternLayout.2 new file mode 100644 index 0000000000..82e6336909 --- /dev/null +++ b/tests/witness/patternLayout.2 @@ -0,0 +1,84 @@ + [main] TRACE rnLayoutTestCase - Message 0 + [main] TRACE root - Message 0 + [main] DEBUG rnLayoutTestCase - Message 1 + [main] DEBUG root - Message 1 + [main] INFO rnLayoutTestCase - Message 2 + [main] INFO root - Message 2 + [main] WARN rnLayoutTestCase - Message 3 + [main] WARN root - Message 3 + [main] ERROR rnLayoutTestCase - Message 4 + [main] ERROR root - Message 4 + [main] FATAL rnLayoutTestCase - Message 5 + [main] FATAL root - Message 5 + [main] TRACE rnLayoutTestCase - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test2(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] DEBUG rnLayoutTestCase - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test2(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] INFO rnLayoutTestCase - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test2(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] WARN rnLayoutTestCase - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test2(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] ERROR rnLayoutTestCase - Message 10 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test2(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] FATAL rnLayoutTestCase - Message 11 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test2(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/patternLayout.3 b/tests/witness/patternLayout.3 new file mode 100644 index 0000000000..b30661136a --- /dev/null +++ b/tests/witness/patternLayout.3 @@ -0,0 +1,84 @@ + [main] TRACE rnLayoutTestCase - Message 0 + [main] TRACE root - Message 0 + [main] DEBUG rnLayoutTestCase - Message 1 + [main] DEBUG root - Message 1 + [main] INFO rnLayoutTestCase - Message 2 + [main] INFO root - Message 2 + [main] WARN rnLayoutTestCase - Message 3 + [main] WARN root - Message 3 + [main] ERROR rnLayoutTestCase - Message 4 + [main] ERROR root - Message 4 + [main] FATAL rnLayoutTestCase - Message 5 + [main] FATAL root - Message 5 + [main] TRACE rnLayoutTestCase - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test3(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] DEBUG rnLayoutTestCase - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test3(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] INFO rnLayoutTestCase - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test3(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] WARN rnLayoutTestCase - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test3(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] ERROR rnLayoutTestCase - Message 10 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test3(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] FATAL rnLayoutTestCase - Message 11 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test3(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/patternLayout.4 b/tests/witness/patternLayout.4 new file mode 100644 index 0000000000..b807e55b95 --- /dev/null +++ b/tests/witness/patternLayout.4 @@ -0,0 +1,84 @@ + [main] TRACE rnLayoutTestCase - Message 0 + [main] TRACE root - Message 0 + [main] DEBUG rnLayoutTestCase - Message 1 + [main] DEBUG root - Message 1 + [main] INFO rnLayoutTestCase - Message 2 + [main] INFO root - Message 2 + [main] WARN rnLayoutTestCase - Message 3 + [main] WARN root - Message 3 + [main] ERROR rnLayoutTestCase - Message 4 + [main] ERROR root - Message 4 + [main] FATAL rnLayoutTestCase - Message 5 + [main] FATAL root - Message 5 + [main] TRACE rnLayoutTestCase - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test4(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] DEBUG rnLayoutTestCase - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test4(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] INFO rnLayoutTestCase - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test4(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] WARN rnLayoutTestCase - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test4(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] ERROR rnLayoutTestCase - Message 10 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test4(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] FATAL rnLayoutTestCase - Message 11 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test4(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/patternLayout.5 b/tests/witness/patternLayout.5 new file mode 100644 index 0000000000..e45c5cbc03 --- /dev/null +++ b/tests/witness/patternLayout.5 @@ -0,0 +1,84 @@ + [main] TRACE rnLayoutTestCase - Message 0 + [main] TRACE root - Message 0 + [main] DEBUG rnLayoutTestCase - Message 1 + [main] DEBUG root - Message 1 + [main] INFO rnLayoutTestCase - Message 2 + [main] INFO root - Message 2 + [main] WARN rnLayoutTestCase - Message 3 + [main] WARN root - Message 3 + [main] ERROR rnLayoutTestCase - Message 4 + [main] ERROR root - Message 4 + [main] FATAL rnLayoutTestCase - Message 5 + [main] FATAL root - Message 5 + [main] TRACE rnLayoutTestCase - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test5(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] DEBUG rnLayoutTestCase - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test5(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] INFO rnLayoutTestCase - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test5(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] WARN rnLayoutTestCase - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test5(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] ERROR rnLayoutTestCase - Message 10 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test5(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] FATAL rnLayoutTestCase - Message 11 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test5(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/patternLayout.6 b/tests/witness/patternLayout.6 new file mode 100644 index 0000000000..6140e468ea --- /dev/null +++ b/tests/witness/patternLayout.6 @@ -0,0 +1,84 @@ + [main] TRACE rnLayoutTestCase - Message 0 + [main] TRACE root - Message 0 + [main] DEBUG rnLayoutTestCase - Message 1 + [main] DEBUG root - Message 1 + [main] INFO rnLayoutTestCase - Message 2 + [main] INFO root - Message 2 + [main] WARN rnLayoutTestCase - Message 3 + [main] WARN root - Message 3 + [main] ERROR rnLayoutTestCase - Message 4 + [main] ERROR root - Message 4 + [main] FATAL rnLayoutTestCase - Message 5 + [main] FATAL root - Message 5 + [main] TRACE rnLayoutTestCase - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test6(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] DEBUG rnLayoutTestCase - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test6(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] INFO rnLayoutTestCase - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test6(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] WARN rnLayoutTestCase - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test6(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] ERROR rnLayoutTestCase - Message 10 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test6(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] FATAL rnLayoutTestCase - Message 11 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test6(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/patternLayout.7 b/tests/witness/patternLayout.7 new file mode 100644 index 0000000000..7a802bc49d --- /dev/null +++ b/tests/witness/patternLayout.7 @@ -0,0 +1,84 @@ + [main] TRACE rnLayoutTestCase - Message 0 + [main] TRACE root - Message 0 + [main] DEBUG rnLayoutTestCase - Message 1 + [main] DEBUG root - Message 1 + [main] INFO rnLayoutTestCase - Message 2 + [main] INFO root - Message 2 + [main] WARN rnLayoutTestCase - Message 3 + [main] WARN root - Message 3 + [main] ERROR rnLayoutTestCase - Message 4 + [main] ERROR root - Message 4 + [main] FATAL rnLayoutTestCase - Message 5 + [main] FATAL root - Message 5 + [main] TRACE rnLayoutTestCase - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test7(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] DEBUG rnLayoutTestCase - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test7(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] INFO rnLayoutTestCase - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test7(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] WARN rnLayoutTestCase - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test7(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] ERROR rnLayoutTestCase - Message 10 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test7(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] FATAL rnLayoutTestCase - Message 11 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test7(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/patternLayout.8 b/tests/witness/patternLayout.8 new file mode 100644 index 0000000000..30cb5cb584 --- /dev/null +++ b/tests/witness/patternLayout.8 @@ -0,0 +1,84 @@ + [main] TRACE rnLayoutTestCase - Message 0 + [main] TRACE root - Message 0 + [main] DEBUG rnLayoutTestCase - Message 1 + [main] DEBUG root - Message 1 + [main] INFO rnLayoutTestCase - Message 2 + [main] INFO root - Message 2 + [main] WARN rnLayoutTestCase - Message 3 + [main] WARN root - Message 3 + [main] ERROR rnLayoutTestCase - Message 4 + [main] ERROR root - Message 4 + [main] FATAL rnLayoutTestCase - Message 5 + [main] FATAL root - Message 5 + [main] TRACE rnLayoutTestCase - Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test8(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] DEBUG rnLayoutTestCase - Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test8(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] INFO rnLayoutTestCase - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test8(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] WARN rnLayoutTestCase - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test8(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] ERROR rnLayoutTestCase - Message 10 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test8(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] FATAL rnLayoutTestCase - Message 11 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test8(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/patternLayout.9 b/tests/witness/patternLayout.9 new file mode 100644 index 0000000000..7b54f6da0f --- /dev/null +++ b/tests/witness/patternLayout.9 @@ -0,0 +1,84 @@ +[main] TRACE rnLayoutTestCase : Message 0 +[main] TRACE root : Message 0 +[main] DEBUG rnLayoutTestCase : Message 1 +[main] DEBUG root : Message 1 +[main] INFO rnLayoutTestCase : Message 2 +[main] INFO root : Message 2 +[main] WARN rnLayoutTestCase : Message 3 +[main] WARN root : Message 3 +[main] ERROR rnLayoutTestCase : Message 4 +[main] ERROR root : Message 4 +[main] FATAL rnLayoutTestCase : Message 5 +[main] FATAL root : Message 5 +[main] TRACE rnLayoutTestCase : Message 6 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test9(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] DEBUG rnLayoutTestCase : Message 7 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test9(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] INFO rnLayoutTestCase : Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test9(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] WARN rnLayoutTestCase : Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test9(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] ERROR rnLayoutTestCase : Message 10 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test9(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +[main] FATAL rnLayoutTestCase : Message 11 +java.lang.Exception: Just testing + at org.apache.log4j.PatternLayoutTestCase.common(PatternLayoutTestCase.java:XXX) + at org.apache.log4j.PatternLayoutTestCase.test9(PatternLayoutTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/patternLayout.mdc.1 b/tests/witness/patternLayout.mdc.1 new file mode 100644 index 0000000000..9bf65405ae --- /dev/null +++ b/tests/witness/patternLayout.mdc.1 @@ -0,0 +1 @@ +DEBUG - Hello World {{key1,va11}{key2,va12}} \ No newline at end of file diff --git a/tests/witness/patternLayout.mdc.clear b/tests/witness/patternLayout.mdc.clear new file mode 100644 index 0000000000..aa71f63b8a --- /dev/null +++ b/tests/witness/patternLayout.mdc.clear @@ -0,0 +1,2 @@ +DEBUG - Hello World {{key1,va11}{key2,va12}} +DEBUG - Hello World {} \ No newline at end of file diff --git a/tests/witness/plugins.PluginTestCase.test1.txt b/tests/witness/plugins.PluginTestCase.test1.txt deleted file mode 100644 index bc22637786..0000000000 --- a/tests/witness/plugins.PluginTestCase.test1.txt +++ /dev/null @@ -1,24 +0,0 @@ -INFO - test 1.1 - basic starting/stopping -INFO - starting plugin1-id1 -INFO - stopping plugin1-id1 using plugin object -DEBUG - plugin1-id1 already shutdown -INFO - test 1.2 - restarting and starting when already started -INFO - restarting plugin1-id1 -INFO - restarting plugin1-id1 again -DEBUG - plugin1-id1 already shutdown -INFO - test 1.3- stopping and stopping when already stopped -INFO - stopping plugin1-id1 -DEBUG - plugin1-id1 already shutdown -INFO - stopping plugin1-id1 again -INFO - test 1.4 - restarting then stopping by plugin name -INFO - starting plugin1-id1 -INFO - stopping plugin1-id1 using plugin name -DEBUG - plugin1-id1 already shutdown -INFO - stopping plugin1-id1 using plugin object -INFO - stopping all plugins -DEBUG - plugin1-id1 is inactive -INFO - plugin1-id1 is inactive -DEBUG - plugin2-id4 is inactive -INFO - plugin2-id4 is inactive -INFO - stopping all plugins again -WARN - Ignoring attempt to remove a non-registered LoggerRepositoryEventListener. \ No newline at end of file diff --git a/tests/witness/plugins.PluginTestCase.test2.txt b/tests/witness/plugins.PluginTestCase.test2.txt deleted file mode 100644 index 1d9813bfa3..0000000000 --- a/tests/witness/plugins.PluginTestCase.test2.txt +++ /dev/null @@ -1,63 +0,0 @@ -INFO - test 2.1 - starting plugins in multiple repositories -INFO - starting plugin1-id1 in repository1 -DEBUG - plugin1-id1 is inactive -DEBUG - plugin1-id1 activated -INFO - returned plugin is plugin1-id1 in repository1 -INFO - starting plugin2-id2 in repository2 -DEBUG - plugin2-id2 is inactive -DEBUG - plugin2-id2 activated -INFO - returned plugin is plugin2-id2 in repository2 -INFO - test 2.2 - stopping plugins in multiple repositories -INFO - stopping plugin1-id1 in repository1 -DEBUG - plugin1-id1 shutdown -INFO - returned plugin is plugin1-id1 in repository1 -INFO - stopping plugin2-id2 in repository2 -DEBUG - plugin2-id2 shutdown -INFO - returned plugin is plugin2-id2 in repository2 -INFO - test 2.3 - restarting plugins in different repositories -INFO - starting plugin1-id1 in repository2 -DEBUG - plugin1-id1 is inactive -DEBUG - plugin1-id1 activated -INFO - returned plugin is plugin1-id1 in repository2 -INFO - starting plugin2-id2 in repository1 -DEBUG - plugin2-id2 is inactive -DEBUG - plugin2-id2 activated -INFO - returned plugin is plugin2-id2 in repository1 -INFO - test 2.4 - stopping plugins using stopAll -INFO - stopping all plugins in repository1 -DEBUG - plugin2-id2 shutdown -INFO - stopping all plugins in repository2 -DEBUG - plugin1-id1 shutdown -INFO - test 2.5 - starting a plugin already active in another repository -INFO - starting plugin1-id1 in repository1 -DEBUG - plugin1-id1 is inactive -DEBUG - plugin1-id1 activated -INFO - returned plugin is plugin1-id1 in repository1 -INFO - starting plugin2-id2 in repository2 -DEBUG - plugin2-id2 is inactive -DEBUG - plugin2-id2 activated -INFO - returned plugin is plugin2-id2 in repository2 -INFO - restarting plugin1-id1 in repository2 -DEBUG - plugin1-id1 is active -INFO - returned plugin is plugin1-id1 in repository1 -INFO - restarting plugin2-id2 in repository1 -DEBUG - plugin2-id2 is active -INFO - returned plugin is plugin2-id2 in repository2 -INFO - test 2.6 - handle repository reset -INFO - resetting repository1 -DEBUG - plugin1-id1 shutdown -INFO - resetting repository2 -DEBUG - plugin2-id2 shutdown -INFO - test 2.7 - handle repository shutdown -INFO - starting plugin1-id1 in repository1 -DEBUG - plugin1-id1 is inactive -DEBUG - plugin1-id1 activated -INFO - returned plugin is plugin1-id1 in repository1 -INFO - starting plugin2-id2 in repository2 -DEBUG - plugin2-id2 is inactive -DEBUG - plugin2-id2 activated -INFO - returned plugin is plugin2-id2 in repository2 -INFO - shutting down repository1 -DEBUG - plugin1-id1 shutdown -INFO - shutting down repository2 -DEBUG - plugin2-id2 shutdown diff --git a/src/main/java/org/apache/log4j/test/witness/definit.2 b/tests/witness/prudent similarity index 100% rename from src/main/java/org/apache/log4j/test/witness/definit.2 rename to tests/witness/prudent diff --git a/tests/witness/rolling/renaming.0 b/tests/witness/rolling/renaming.0 deleted file mode 100644 index 7fda412202..0000000000 --- a/tests/witness/rolling/renaming.0 +++ /dev/null @@ -1 +0,0 @@ -RenamingTest - Hello 0 diff --git a/tests/witness/rolling/renaming.1 b/tests/witness/rolling/renaming.1 deleted file mode 100644 index 045554488b..0000000000 --- a/tests/witness/rolling/renaming.1 +++ /dev/null @@ -1 +0,0 @@ -RenamingTest - Hello 1 diff --git a/tests/witness/rolling/renaming.2 b/tests/witness/rolling/renaming.2 deleted file mode 100755 index f32daeb512..0000000000 --- a/tests/witness/rolling/renaming.2 +++ /dev/null @@ -1,2 +0,0 @@ -RenamingTest - Hello 0 -RenamingTest - Hello 1 diff --git a/tests/witness/rolling/sbr-test2.0 b/tests/witness/rolling/sbr-test2.0 deleted file mode 100644 index ddeb00f7e3..0000000000 --- a/tests/witness/rolling/sbr-test2.0 +++ /dev/null @@ -1,10 +0,0 @@ -Hello--10 -Hello--11 -Hello--12 -Hello--13 -Hello--14 -Hello--15 -Hello--16 -Hello--17 -Hello--18 -Hello--19 diff --git a/tests/witness/rolling/sbr-test2.1 b/tests/witness/rolling/sbr-test2.1 deleted file mode 100644 index e7850d14f8..0000000000 --- a/tests/witness/rolling/sbr-test2.1 +++ /dev/null @@ -1,10 +0,0 @@ -Hello---0 -Hello---1 -Hello---2 -Hello---3 -Hello---4 -Hello---5 -Hello---6 -Hello---7 -Hello---8 -Hello---9 diff --git a/tests/witness/rolling/sbr-test2.log b/tests/witness/rolling/sbr-test2.log deleted file mode 100644 index 7243328826..0000000000 --- a/tests/witness/rolling/sbr-test2.log +++ /dev/null @@ -1,5 +0,0 @@ -Hello--20 -Hello--21 -Hello--22 -Hello--23 -Hello--24 diff --git a/tests/witness/rolling/sbr-test3.0.gz b/tests/witness/rolling/sbr-test3.0.gz deleted file mode 100644 index 0e208b2873..0000000000 Binary files a/tests/witness/rolling/sbr-test3.0.gz and /dev/null differ diff --git a/tests/witness/rolling/sbr-test3.1.gz b/tests/witness/rolling/sbr-test3.1.gz deleted file mode 100644 index 2d00fc4f89..0000000000 Binary files a/tests/witness/rolling/sbr-test3.1.gz and /dev/null differ diff --git a/tests/witness/rolling/sbr-test3.log b/tests/witness/rolling/sbr-test3.log deleted file mode 100644 index 7243328826..0000000000 --- a/tests/witness/rolling/sbr-test3.log +++ /dev/null @@ -1,5 +0,0 @@ -Hello--20 -Hello--21 -Hello--22 -Hello--23 -Hello--24 diff --git a/tests/witness/rolling/sbr-test4.log b/tests/witness/rolling/sbr-test4.log deleted file mode 100644 index 2feaa334de..0000000000 --- a/tests/witness/rolling/sbr-test4.log +++ /dev/null @@ -1,25 +0,0 @@ -Hello---0 -Hello---1 -Hello---2 -Hello---3 -Hello---4 -Hello---5 -Hello---6 -Hello---7 -Hello---8 -Hello---9 -Hello--10 -Hello--11 -Hello--12 -Hello--13 -Hello--14 -Hello--15 -Hello--16 -Hello--17 -Hello--18 -Hello--19 -Hello--20 -Hello--21 -Hello--22 -Hello--23 -Hello--24 diff --git a/tests/witness/rolling/tbr-test1.0 b/tests/witness/rolling/tbr-test1.0 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/witness/rolling/tbr-test1.1 b/tests/witness/rolling/tbr-test1.1 deleted file mode 100644 index 6ef940568b..0000000000 --- a/tests/witness/rolling/tbr-test1.1 +++ /dev/null @@ -1,2 +0,0 @@ -TimeBasedRollingTest - Hello---0 -TimeBasedRollingTest - Hello---1 diff --git a/tests/witness/rolling/tbr-test1.2 b/tests/witness/rolling/tbr-test1.2 deleted file mode 100644 index 332609b6d2..0000000000 --- a/tests/witness/rolling/tbr-test1.2 +++ /dev/null @@ -1,2 +0,0 @@ -TimeBasedRollingTest - Hello---2 -TimeBasedRollingTest - Hello---3 diff --git a/tests/witness/rolling/tbr-test1.3 b/tests/witness/rolling/tbr-test1.3 deleted file mode 100644 index 567dcb73f0..0000000000 --- a/tests/witness/rolling/tbr-test1.3 +++ /dev/null @@ -1 +0,0 @@ -TimeBasedRollingTest - Hello---4 diff --git a/tests/witness/rolling/tbr-test2.0 b/tests/witness/rolling/tbr-test2.0 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/witness/rolling/tbr-test2.1 b/tests/witness/rolling/tbr-test2.1 deleted file mode 100644 index 6ef940568b..0000000000 --- a/tests/witness/rolling/tbr-test2.1 +++ /dev/null @@ -1,2 +0,0 @@ -TimeBasedRollingTest - Hello---0 -TimeBasedRollingTest - Hello---1 diff --git a/tests/witness/rolling/tbr-test2.2 b/tests/witness/rolling/tbr-test2.2 deleted file mode 100644 index 332609b6d2..0000000000 --- a/tests/witness/rolling/tbr-test2.2 +++ /dev/null @@ -1,2 +0,0 @@ -TimeBasedRollingTest - Hello---2 -TimeBasedRollingTest - Hello---3 diff --git a/tests/witness/rolling/tbr-test2.3 b/tests/witness/rolling/tbr-test2.3 deleted file mode 100644 index 567dcb73f0..0000000000 --- a/tests/witness/rolling/tbr-test2.3 +++ /dev/null @@ -1 +0,0 @@ -TimeBasedRollingTest - Hello---4 diff --git a/tests/witness/rolling/tbr-test3.0.gz b/tests/witness/rolling/tbr-test3.0.gz deleted file mode 100644 index 351e7dc65f..0000000000 Binary files a/tests/witness/rolling/tbr-test3.0.gz and /dev/null differ diff --git a/tests/witness/rolling/tbr-test3.1.gz b/tests/witness/rolling/tbr-test3.1.gz deleted file mode 100644 index 827245c3d4..0000000000 Binary files a/tests/witness/rolling/tbr-test3.1.gz and /dev/null differ diff --git a/tests/witness/rolling/tbr-test3.2.gz b/tests/witness/rolling/tbr-test3.2.gz deleted file mode 100644 index 9498ef46a3..0000000000 Binary files a/tests/witness/rolling/tbr-test3.2.gz and /dev/null differ diff --git a/tests/witness/rolling/tbr-test3.3 b/tests/witness/rolling/tbr-test3.3 deleted file mode 100644 index 567dcb73f0..0000000000 --- a/tests/witness/rolling/tbr-test3.3 +++ /dev/null @@ -1 +0,0 @@ -TimeBasedRollingTest - Hello---4 diff --git a/tests/witness/rolling/tbr-test4.0 b/tests/witness/rolling/tbr-test4.0 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/witness/rolling/tbr-test4.1 b/tests/witness/rolling/tbr-test4.1 deleted file mode 100644 index 6ef940568b..0000000000 --- a/tests/witness/rolling/tbr-test4.1 +++ /dev/null @@ -1,2 +0,0 @@ -TimeBasedRollingTest - Hello---0 -TimeBasedRollingTest - Hello---1 diff --git a/tests/witness/rolling/tbr-test4.2 b/tests/witness/rolling/tbr-test4.2 deleted file mode 100644 index 332609b6d2..0000000000 --- a/tests/witness/rolling/tbr-test4.2 +++ /dev/null @@ -1,2 +0,0 @@ -TimeBasedRollingTest - Hello---2 -TimeBasedRollingTest - Hello---3 diff --git a/tests/witness/rolling/tbr-test4.3 b/tests/witness/rolling/tbr-test4.3 deleted file mode 100644 index 567dcb73f0..0000000000 --- a/tests/witness/rolling/tbr-test4.3 +++ /dev/null @@ -1 +0,0 @@ -TimeBasedRollingTest - Hello---4 diff --git a/tests/witness/rolling/tbr-test5.0 b/tests/witness/rolling/tbr-test5.0 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/witness/rolling/tbr-test5.1 b/tests/witness/rolling/tbr-test5.1 deleted file mode 100644 index 6ef940568b..0000000000 --- a/tests/witness/rolling/tbr-test5.1 +++ /dev/null @@ -1,2 +0,0 @@ -TimeBasedRollingTest - Hello---0 -TimeBasedRollingTest - Hello---1 diff --git a/tests/witness/rolling/tbr-test5.2 b/tests/witness/rolling/tbr-test5.2 deleted file mode 100644 index 332609b6d2..0000000000 --- a/tests/witness/rolling/tbr-test5.2 +++ /dev/null @@ -1,2 +0,0 @@ -TimeBasedRollingTest - Hello---2 -TimeBasedRollingTest - Hello---3 diff --git a/tests/witness/rolling/tbr-test5.3 b/tests/witness/rolling/tbr-test5.3 deleted file mode 100644 index 567dcb73f0..0000000000 --- a/tests/witness/rolling/tbr-test5.3 +++ /dev/null @@ -1 +0,0 @@ -TimeBasedRollingTest - Hello---4 diff --git a/tests/witness/rolling/tbr-test6.0.gz b/tests/witness/rolling/tbr-test6.0.gz deleted file mode 100644 index 001322f84b..0000000000 Binary files a/tests/witness/rolling/tbr-test6.0.gz and /dev/null differ diff --git a/tests/witness/rolling/tbr-test6.1.gz b/tests/witness/rolling/tbr-test6.1.gz deleted file mode 100644 index 298b2c3d0c..0000000000 Binary files a/tests/witness/rolling/tbr-test6.1.gz and /dev/null differ diff --git a/tests/witness/rolling/tbr-test6.2.gz b/tests/witness/rolling/tbr-test6.2.gz deleted file mode 100644 index 6f429b2cd3..0000000000 Binary files a/tests/witness/rolling/tbr-test6.2.gz and /dev/null differ diff --git a/tests/witness/rolling/tbr-test6.3 b/tests/witness/rolling/tbr-test6.3 deleted file mode 100644 index 567dcb73f0..0000000000 --- a/tests/witness/rolling/tbr-test6.3 +++ /dev/null @@ -1 +0,0 @@ -TimeBasedRollingTest - Hello---4 diff --git a/tests/witness/serialization/exception.bin b/tests/witness/serialization/exception.bin index ec6a5bd8c9..87b0c1db0c 100644 Binary files a/tests/witness/serialization/exception.bin and b/tests/witness/serialization/exception.bin differ diff --git a/tests/witness/serialization/location.bin b/tests/witness/serialization/location.bin index cb98ecc562..c7988504f2 100644 Binary files a/tests/witness/serialization/location.bin and b/tests/witness/serialization/location.bin differ diff --git a/tests/witness/serialization/mdc.bin b/tests/witness/serialization/mdc.bin index 6c80485109..42e994e757 100644 Binary files a/tests/witness/serialization/mdc.bin and b/tests/witness/serialization/mdc.bin differ diff --git a/tests/witness/serialization/ndc.bin b/tests/witness/serialization/ndc.bin index 7267d818d3..7f434550e9 100644 Binary files a/tests/witness/serialization/ndc.bin and b/tests/witness/serialization/ndc.bin differ diff --git a/tests/witness/serialization/simple.bin b/tests/witness/serialization/simple.bin index a8215c3215..c31f3cffb7 100644 Binary files a/tests/witness/serialization/simple.bin and b/tests/witness/serialization/simple.bin differ diff --git a/tests/witness/simple b/tests/witness/simple index ce46eab836..77cef876ab 100644 --- a/tests/witness/simple +++ b/tests/witness/simple @@ -22,16 +22,21 @@ ERROR - Message 20 WARN - Message 21 INFO - Message 22 DEBUG - Message 23 +TRACE - Message 24 +FATAL - Message 25 +ERROR - Message 26 +WARN - Message 27 +INFO - Message 28 +DEBUG - Message 29 java.lang.Exception: Just testing. - at org.apache.log4j.MinimumTest.common(X) - at org.apache.log4j.MinimumTest.simple(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -INFO - Messages should bear numbers 0 through 23. + at org.apache.log4j.MinimumTestCase.common(MinimumTestCase.java:XXX) + at org.apache.log4j.MinimumTestCase.simple(MinimumTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +INFO - Messages should bear numbers 0 through 29. diff --git a/tests/witness/socketServer.1 b/tests/witness/socketServer.1 new file mode 100644 index 0000000000..113f262eec --- /dev/null +++ b/tests/witness/socketServer.1 @@ -0,0 +1,31 @@ +TRACE T1 [main] org.apache.log4j.net.SocketServerTestCase Message 1 +TRACE T1 [main] root Message 2 +DEBUG T1 [main] org.apache.log4j.net.SocketServerTestCase Message 3 +DEBUG T1 [main] root Message 4 + INFO T1 [main] org.apache.log4j.net.SocketServerTestCase Message 5 + WARN T1 [main] org.apache.log4j.net.SocketServerTestCase Message 6 +LETHAL T1 [main] org.apache.log4j.net.SocketServerTestCase Message 7 +DEBUG T1 [main] org.apache.log4j.net.SocketServerTestCase Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.net.SocketServerTestCase.common(SocketServerTestCase.java:XXX) + at org.apache.log4j.net.SocketServerTestCase.test1(SocketServerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +ERROR T1 [main] root Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.net.SocketServerTestCase.common(SocketServerTestCase.java:XXX) + at org.apache.log4j.net.SocketServerTestCase.test1(SocketServerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/socketServer.2 b/tests/witness/socketServer.2 new file mode 100644 index 0000000000..3ee37c1a51 --- /dev/null +++ b/tests/witness/socketServer.2 @@ -0,0 +1,31 @@ +TRACE T2 [main] ? (?:?) Message 1 +TRACE T2 [main] ? (?:?) Message 2 +DEBUG T2 [main] ? (?:?) Message 3 +DEBUG T2 [main] ? (?:?) Message 4 + INFO T2 [main] ? (?:?) Message 5 + WARN T2 [main] ? (?:?) Message 6 +LETHAL T2 [main] ? (?:?) Message 7 +DEBUG T2 [main] ? (?:?) Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.net.SocketServerTestCase.common(SocketServerTestCase.java:XXX) + at org.apache.log4j.net.SocketServerTestCase.test2(SocketServerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +ERROR T2 [main] ? (?:?) Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.net.SocketServerTestCase.common(SocketServerTestCase.java:XXX) + at org.apache.log4j.net.SocketServerTestCase.test2(SocketServerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/socketServer.3 b/tests/witness/socketServer.3 new file mode 100644 index 0000000000..de184bbd8c --- /dev/null +++ b/tests/witness/socketServer.3 @@ -0,0 +1,31 @@ +TRACE T3 [main] org.apache.log4j.net.SocketServerTestCase (SocketServerTestCase.java:XXX) Message 1 +TRACE T3 [main] org.apache.log4j.net.SocketServerTestCase (SocketServerTestCase.java:XXX) Message 2 +DEBUG T3 [main] org.apache.log4j.net.SocketServerTestCase (SocketServerTestCase.java:XXX) Message 3 +DEBUG T3 [main] org.apache.log4j.net.SocketServerTestCase (SocketServerTestCase.java:XXX) Message 4 + INFO T3 [main] org.apache.log4j.net.SocketServerTestCase (SocketServerTestCase.java:XXX) Message 5 + WARN T3 [main] org.apache.log4j.net.SocketServerTestCase (SocketServerTestCase.java:XXX) Message 6 +LETHAL T3 [main] org.apache.log4j.net.SocketServerTestCase (SocketServerTestCase.java:XXX) Message 7 +DEBUG T3 [main] org.apache.log4j.net.SocketServerTestCase (SocketServerTestCase.java:XXX) Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.net.SocketServerTestCase.common(SocketServerTestCase.java:XXX) + at org.apache.log4j.net.SocketServerTestCase.test3(SocketServerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +ERROR T3 [main] org.apache.log4j.net.SocketServerTestCase (SocketServerTestCase.java:XXX) Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.net.SocketServerTestCase.common(SocketServerTestCase.java:XXX) + at org.apache.log4j.net.SocketServerTestCase.test3(SocketServerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/socketServer.4 b/tests/witness/socketServer.4 new file mode 100644 index 0000000000..69236688b4 --- /dev/null +++ b/tests/witness/socketServer.4 @@ -0,0 +1,31 @@ +TRACE some T4 MDC-TEST4 [main] SocketServerTestCase - Message 1 +TRACE some T4 MDC-TEST4 [main] root - Message 2 +DEBUG some T4 MDC-TEST4 [main] SocketServerTestCase - Message 3 +DEBUG some T4 MDC-TEST4 [main] root - Message 4 + INFO some T4 MDC-TEST4 [main] SocketServerTestCase - Message 5 + WARN some T4 MDC-TEST4 [main] SocketServerTestCase - Message 6 +LETHAL some T4 MDC-TEST4 [main] SocketServerTestCase - Message 7 +DEBUG some T4 MDC-TEST4 [main] SocketServerTestCase - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.net.SocketServerTestCase.common(SocketServerTestCase.java:XXX) + at org.apache.log4j.net.SocketServerTestCase.test4(SocketServerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +ERROR some T4 MDC-TEST4 [main] root - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.net.SocketServerTestCase.common(SocketServerTestCase.java:XXX) + at org.apache.log4j.net.SocketServerTestCase.test4(SocketServerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/socketServer.5 b/tests/witness/socketServer.5 new file mode 100644 index 0000000000..cde6de7152 --- /dev/null +++ b/tests/witness/socketServer.5 @@ -0,0 +1,31 @@ +TRACE some5 T5 MDC-TEST5 [main] SocketServerTestCase - Message 1 +TRACE some5 T5 MDC-TEST5 [main] root - Message 2 +DEBUG some5 T5 MDC-TEST5 [main] SocketServerTestCase - Message 3 +DEBUG some5 T5 MDC-TEST5 [main] root - Message 4 + INFO some5 T5 MDC-TEST5 [main] SocketServerTestCase - Message 5 + WARN some5 T5 MDC-TEST5 [main] SocketServerTestCase - Message 6 +LETHAL some5 T5 MDC-TEST5 [main] SocketServerTestCase - Message 7 +DEBUG some5 T5 MDC-TEST5 [main] SocketServerTestCase - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.net.SocketServerTestCase.common(SocketServerTestCase.java:XXX) + at org.apache.log4j.net.SocketServerTestCase.test5(SocketServerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +ERROR some5 T5 MDC-TEST5 [main] root - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.net.SocketServerTestCase.common(SocketServerTestCase.java:XXX) + at org.apache.log4j.net.SocketServerTestCase.test5(SocketServerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/socketServer.6 b/tests/witness/socketServer.6 new file mode 100644 index 0000000000..ae9a686040 --- /dev/null +++ b/tests/witness/socketServer.6 @@ -0,0 +1,31 @@ +TRACE some6 T6 client-test6 MDC-TEST6 [main] SocketServerTestCase - Message 1 +TRACE some6 T6 client-test6 MDC-TEST6 [main] root - Message 2 +DEBUG some6 T6 client-test6 MDC-TEST6 [main] SocketServerTestCase - Message 3 +DEBUG some6 T6 client-test6 MDC-TEST6 [main] root - Message 4 + INFO some6 T6 client-test6 MDC-TEST6 [main] SocketServerTestCase - Message 5 + WARN some6 T6 client-test6 MDC-TEST6 [main] SocketServerTestCase - Message 6 +LETHAL some6 T6 client-test6 MDC-TEST6 [main] SocketServerTestCase - Message 7 +DEBUG some6 T6 client-test6 MDC-TEST6 [main] SocketServerTestCase - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.net.SocketServerTestCase.common(SocketServerTestCase.java:XXX) + at org.apache.log4j.net.SocketServerTestCase.test6(SocketServerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +ERROR some6 T6 client-test6 MDC-TEST6 [main] root - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.net.SocketServerTestCase.common(SocketServerTestCase.java:XXX) + at org.apache.log4j.net.SocketServerTestCase.test6(SocketServerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/socketServer.7 b/tests/witness/socketServer.7 new file mode 100644 index 0000000000..3ea7428cbd --- /dev/null +++ b/tests/witness/socketServer.7 @@ -0,0 +1,31 @@ +TRACE some7 T7 client-test7 MDC-TEST7 [main] SocketServerTestCase - Message 1 +TRACE some7 T7 client-test7 MDC-TEST7 [main] root - Message 2 +DEBUG some7 T7 client-test7 MDC-TEST7 [main] SocketServerTestCase - Message 3 +DEBUG some7 T7 client-test7 MDC-TEST7 [main] root - Message 4 + INFO some7 T7 client-test7 MDC-TEST7 [main] SocketServerTestCase - Message 5 + WARN some7 T7 client-test7 MDC-TEST7 [main] SocketServerTestCase - Message 6 +LETHAL some7 T7 client-test7 MDC-TEST7 [main] SocketServerTestCase - Message 7 +DEBUG some7 T7 client-test7 MDC-TEST7 [main] SocketServerTestCase - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.net.SocketServerTestCase.common(SocketServerTestCase.java:XXX) + at org.apache.log4j.net.SocketServerTestCase.test7(SocketServerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +ERROR some7 T7 client-test7 MDC-TEST7 [main] root - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.net.SocketServerTestCase.common(SocketServerTestCase.java:XXX) + at org.apache.log4j.net.SocketServerTestCase.test7(SocketServerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/socketServer.8 b/tests/witness/socketServer.8 new file mode 100644 index 0000000000..c317ac7aca --- /dev/null +++ b/tests/witness/socketServer.8 @@ -0,0 +1,31 @@ +TRACE some8 T8 shortSocketServer MDC-TEST8 [main] SocketServerTestCase - Message 1 +TRACE some8 T8 shortSocketServer MDC-TEST8 [main] root - Message 2 +DEBUG some8 T8 shortSocketServer MDC-TEST8 [main] SocketServerTestCase - Message 3 +DEBUG some8 T8 shortSocketServer MDC-TEST8 [main] root - Message 4 + INFO some8 T8 shortSocketServer MDC-TEST8 [main] SocketServerTestCase - Message 5 + WARN some8 T8 shortSocketServer MDC-TEST8 [main] SocketServerTestCase - Message 6 +LETHAL some8 T8 shortSocketServer MDC-TEST8 [main] SocketServerTestCase - Message 7 +DEBUG some8 T8 shortSocketServer MDC-TEST8 [main] SocketServerTestCase - Message 8 +java.lang.Exception: Just testing + at org.apache.log4j.net.SocketServerTestCase.common(SocketServerTestCase.java:XXX) + at org.apache.log4j.net.SocketServerTestCase.test8(SocketServerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) +ERROR some8 T8 shortSocketServer MDC-TEST8 [main] root - Message 9 +java.lang.Exception: Just testing + at org.apache.log4j.net.SocketServerTestCase.common(SocketServerTestCase.java:XXX) + at org.apache.log4j.net.SocketServerTestCase.test8(SocketServerTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) diff --git a/tests/witness/ttcc b/tests/witness/ttcc index fb8309f05d..43b7394cd3 100644 --- a/tests/witness/ttcc +++ b/tests/witness/ttcc @@ -17,21 +17,26 @@ [main] WARN DEB - Message 16 [main] INFO DEB - Message 17 [main] DEBUG DEB - Message 18 - [main] FATAL UNDEF - Message 19 - [main] ERROR UNDEF - Message 20 - [main] WARN UNDEF - Message 21 - [main] INFO UNDEF - Message 22 - [main] DEBUG UNDEF - Message 23 + [main] FATAL TRC - Message 19 + [main] ERROR TRC - Message 20 + [main] WARN TRC - Message 21 + [main] INFO TRC - Message 22 + [main] DEBUG TRC - Message 23 + [main] TRACE TRC - Message 24 + [main] FATAL UNDEF - Message 25 + [main] ERROR UNDEF - Message 26 + [main] WARN UNDEF - Message 27 + [main] INFO UNDEF - Message 28 + [main] DEBUG UNDEF - Message 29 java.lang.Exception: Just testing. - at org.apache.log4j.MinimumTest.common(X) - at org.apache.log4j.MinimumTest.ttcc(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] INFO INF - Messages should bear numbers 0 through 23. + at org.apache.log4j.MinimumTestCase.common(MinimumTestCase.java:XXX) + at org.apache.log4j.MinimumTestCase.ttcc(MinimumTestCase.java:XXX) + at junit.framework.TestCase.runTest(TestCase.java:XXX) + at junit.framework.TestCase.runBare(TestCase.java:XXX) + at junit.framework.TestResult$1.protect(TestResult.java:XXX) + at junit.framework.TestResult.runProtected(TestResult.java:XXX) + at junit.framework.TestResult.run(TestResult.java:XXX) + at junit.framework.TestCase.run(TestCase.java:XXX) + at junit.framework.TestSuite.runTest(TestSuite.java:XXX) + at junit.framework.TestSuite.run(TestSuite.java:XXX) + [main] INFO INF - Messages should bear numbers 0 through 29. diff --git a/tests/witness/watchdog/watchdog.FileWatchdog.test1.txt b/tests/witness/watchdog/watchdog.FileWatchdog.test1.txt deleted file mode 100755 index 6a9d6c625c..0000000000 --- a/tests/witness/watchdog/watchdog.FileWatchdog.test1.txt +++ /dev/null @@ -1,9 +0,0 @@ -DEBUG - debug message -INFO - info message -WARN - warn message -ERROR - error message -FATAL - fatal message -INFO - info message -WARN - warn message -ERROR - error message -FATAL - fatal message diff --git a/tests/witness/watchdog/watchdog.FileWatchdog.test2.txt b/tests/witness/watchdog/watchdog.FileWatchdog.test2.txt deleted file mode 100755 index 6a9d6c625c..0000000000 --- a/tests/witness/watchdog/watchdog.FileWatchdog.test2.txt +++ /dev/null @@ -1,9 +0,0 @@ -DEBUG - debug message -INFO - info message -WARN - warn message -ERROR - error message -FATAL - fatal message -INFO - info message -WARN - warn message -ERROR - error message -FATAL - fatal message diff --git a/tests/witness/watchdog/watchdog.FileWatchdog.test5.txt b/tests/witness/watchdog/watchdog.FileWatchdog.test5.txt deleted file mode 100755 index 6a9d6c625c..0000000000 --- a/tests/witness/watchdog/watchdog.FileWatchdog.test5.txt +++ /dev/null @@ -1,9 +0,0 @@ -DEBUG - debug message -INFO - info message -WARN - warn message -ERROR - error message -FATAL - fatal message -INFO - info message -WARN - warn message -ERROR - error message -FATAL - fatal message diff --git a/tests/witness/watchdog/watchdog.FileWatchdog.test6.txt b/tests/witness/watchdog/watchdog.FileWatchdog.test6.txt deleted file mode 100755 index 6a9d6c625c..0000000000 --- a/tests/witness/watchdog/watchdog.FileWatchdog.test6.txt +++ /dev/null @@ -1,9 +0,0 @@ -DEBUG - debug message -INFO - info message -WARN - warn message -ERROR - error message -FATAL - fatal message -INFO - info message -WARN - warn message -ERROR - error message -FATAL - fatal message diff --git a/tests/witness/xml/customLogger.1 b/tests/witness/xml/customLogger.1 deleted file mode 100644 index c32ac93cd9..0000000000 --- a/tests/witness/xml/customLogger.1 +++ /dev/null @@ -1,18 +0,0 @@ -TRACE customLogger.XLoggerTestCase - Message 0 -DEBUG customLogger.XLoggerTestCase - Message 1 -WARN customLogger.XLoggerTestCase - Message 2 -ERROR customLogger.XLoggerTestCase - Message 3 -FATAL customLogger.XLoggerTestCase - Message 4 -DEBUG customLogger.XLoggerTestCase - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.customLogger.XLoggerTestCase.common(X) - at org.apache.log4j.customLogger.XLoggerTestCase.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) \ No newline at end of file diff --git a/tests/witness/xml/dom.A1.1 b/tests/witness/xml/dom.A1.1 deleted file mode 100644 index b8052ada93..0000000000 --- a/tests/witness/xml/dom.A1.1 +++ /dev/null @@ -1,93 +0,0 @@ -DEBUG xml.DOMTest - Message 0 -DEBUG xml.DOMTest - Message 0 -DEBUG root - Message 0 -INFO xml.DOMTest - Message 1 -INFO xml.DOMTest - Message 1 -INFO root - Message 1 -WARN xml.DOMTest - Message 2 -WARN xml.DOMTest - Message 2 -WARN root - Message 2 -ERROR xml.DOMTest - Message 3 -ERROR xml.DOMTest - Message 3 -ERROR root - Message 3 -FATAL xml.DOMTest - Message 4 -FATAL xml.DOMTest - Message 4 -FATAL root - Message 4 -DEBUG xml.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -DEBUG xml.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -DEBUG root - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR xml.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR xml.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR root - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/xml/dom.A1.2 b/tests/witness/xml/dom.A1.2 deleted file mode 100644 index 786b5890db..0000000000 --- a/tests/witness/xml/dom.A1.2 +++ /dev/null @@ -1,93 +0,0 @@ -DEBUG xml.DOMTest - Message 0 -DEBUG xml.DOMTest - Message 0 -DEBUG root - Message 0 -INFO xml.DOMTest - Message 1 -INFO xml.DOMTest - Message 1 -INFO root - Message 1 -WARN xml.DOMTest - Message 2 -WARN xml.DOMTest - Message 2 -WARN root - Message 2 -ERROR xml.DOMTest - Message 3 -ERROR xml.DOMTest - Message 3 -ERROR root - Message 3 -FATAL xml.DOMTest - Message 4 -FATAL xml.DOMTest - Message 4 -FATAL root - Message 4 -DEBUG xml.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test2(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -DEBUG xml.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test2(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -DEBUG root - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test2(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR xml.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test2(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR xml.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test2(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR root - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test2(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/xml/dom.A1.3 b/tests/witness/xml/dom.A1.3 deleted file mode 100644 index e9b37cf316..0000000000 --- a/tests/witness/xml/dom.A1.3 +++ /dev/null @@ -1,93 +0,0 @@ -DEBUG xml.DOMTest - Message 0 -DEBUG xml.DOMTest - Message 0 -DEBUG root - Message 0 -INFO xml.DOMTest - Message 1 -INFO xml.DOMTest - Message 1 -INFO root - Message 1 -WARN xml.DOMTest - Message 2 -WARN xml.DOMTest - Message 2 -WARN root - Message 2 -ERROR xml.DOMTest - Message 3 -ERROR xml.DOMTest - Message 3 -ERROR root - Message 3 -FATAL xml.DOMTest - Message 4 -FATAL xml.DOMTest - Message 4 -FATAL root - Message 4 -DEBUG xml.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test3(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -DEBUG xml.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test3(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -DEBUG root - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test3(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR xml.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test3(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR xml.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test3(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR root - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test3(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/xml/dom.A1.4 b/tests/witness/xml/dom.A1.4 deleted file mode 100644 index fc95564045..0000000000 --- a/tests/witness/xml/dom.A1.4 +++ /dev/null @@ -1,93 +0,0 @@ -DEBUG xml.DOMTest - Message 0 -DEBUG xml.DOMTest - Message 0 -DEBUG root - Message 0 -INFO xml.DOMTest - Message 1 -INFO xml.DOMTest - Message 1 -INFO root - Message 1 -WARN xml.DOMTest - Message 2 -WARN xml.DOMTest - Message 2 -WARN root - Message 2 -ERROR xml.DOMTest - Message 3 -ERROR xml.DOMTest - Message 3 -ERROR root - Message 3 -FATAL xml.DOMTest - Message 4 -FATAL xml.DOMTest - Message 4 -FATAL root - Message 4 -DEBUG xml.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test4(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -DEBUG xml.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test4(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -DEBUG root - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test4(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR xml.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test4(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR xml.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test4(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) -ERROR root - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test4(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/xml/dom.A2.1 b/tests/witness/xml/dom.A2.1 deleted file mode 100644 index 2c600676f7..0000000000 --- a/tests/witness/xml/dom.A2.1 +++ /dev/null @@ -1,62 +0,0 @@ - [main] DEBUG org.apache.log4j.xml.DOMTest - Message 0 - [main] DEBUG root - Message 0 - [main] INFO org.apache.log4j.xml.DOMTest - Message 1 - [main] INFO root - Message 1 - [main] WARN org.apache.log4j.xml.DOMTest - Message 2 - [main] WARN root - Message 2 - [main] ERROR org.apache.log4j.xml.DOMTest - Message 3 - [main] ERROR root - Message 3 - [main] FATAL org.apache.log4j.xml.DOMTest - Message 4 - [main] FATAL root - Message 4 - [main] DEBUG org.apache.log4j.xml.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] DEBUG root - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] ERROR org.apache.log4j.xml.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] ERROR root - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test1(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/xml/dom.A2.2 b/tests/witness/xml/dom.A2.2 deleted file mode 100644 index d004fc335f..0000000000 --- a/tests/witness/xml/dom.A2.2 +++ /dev/null @@ -1,62 +0,0 @@ - [main] DEBUG org.apache.log4j.xml.DOMTest - Message 0 - [main] DEBUG root - Message 0 - [main] INFO org.apache.log4j.xml.DOMTest - Message 1 - [main] INFO root - Message 1 - [main] WARN org.apache.log4j.xml.DOMTest - Message 2 - [main] WARN root - Message 2 - [main] ERROR org.apache.log4j.xml.DOMTest - Message 3 - [main] ERROR root - Message 3 - [main] FATAL org.apache.log4j.xml.DOMTest - Message 4 - [main] FATAL root - Message 4 - [main] DEBUG org.apache.log4j.xml.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test2(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] DEBUG root - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test2(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] ERROR org.apache.log4j.xml.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test2(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] ERROR root - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test2(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/xml/dom.A2.3 b/tests/witness/xml/dom.A2.3 deleted file mode 100644 index acaf4c5322..0000000000 --- a/tests/witness/xml/dom.A2.3 +++ /dev/null @@ -1,62 +0,0 @@ - [main] DEBUG org.apache.log4j.xml.DOMTest - Message 0 - [main] DEBUG root - Message 0 - [main] INFO org.apache.log4j.xml.DOMTest - Message 1 - [main] INFO root - Message 1 - [main] WARN org.apache.log4j.xml.DOMTest - Message 2 - [main] WARN root - Message 2 - [main] ERROR org.apache.log4j.xml.DOMTest - Message 3 - [main] ERROR root - Message 3 - [main] FATAL org.apache.log4j.xml.DOMTest - Message 4 - [main] FATAL root - Message 4 - [main] DEBUG org.apache.log4j.xml.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test3(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] DEBUG root - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test3(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] ERROR org.apache.log4j.xml.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test3(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] ERROR root - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test3(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/xml/dom.A2.4 b/tests/witness/xml/dom.A2.4 deleted file mode 100644 index 85aed732d5..0000000000 --- a/tests/witness/xml/dom.A2.4 +++ /dev/null @@ -1,62 +0,0 @@ - [main] DEBUG org.apache.log4j.xml.DOMTest - Message 0 - [main] DEBUG root - Message 0 - [main] INFO org.apache.log4j.xml.DOMTest - Message 1 - [main] INFO root - Message 1 - [main] WARN org.apache.log4j.xml.DOMTest - Message 2 - [main] WARN root - Message 2 - [main] ERROR org.apache.log4j.xml.DOMTest - Message 3 - [main] ERROR root - Message 3 - [main] FATAL org.apache.log4j.xml.DOMTest - Message 4 - [main] FATAL root - Message 4 - [main] DEBUG org.apache.log4j.xml.DOMTest - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test4(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] DEBUG root - Message 5 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test4(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] ERROR org.apache.log4j.xml.DOMTest - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test4(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) - [main] ERROR root - Message 6 -java.lang.Exception: Just testing - at org.apache.log4j.xml.DOMTest.common(X) - at org.apache.log4j.xml.DOMTest.test4(X) - at java.lang.reflect.Method.invoke(X) - at junit.framework.TestCase.runTest(X) - at junit.framework.TestCase.runBare(X) - at junit.framework.TestResult$1.protect(X) - at junit.framework.TestResult.runProtected(X) - at junit.framework.TestResult.run(X) - at junit.framework.TestCase.run(X) - at junit.framework.TestSuite.runTest(X) - at junit.framework.TestSuite.run(X) diff --git a/tests/witness/xml/xmlLayout.1 b/tests/witness/xml/xmlLayout.1 deleted file mode 100644 index be015dcefc..0000000000 --- a/tests/witness/xml/xmlLayout.1 +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/witness/xml/xmlLayout.2 b/tests/witness/xml/xmlLayout.2 deleted file mode 100644 index 74aff3337b..0000000000 --- a/tests/witness/xml/xmlLayout.2 +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/witness/xml/xmlLayout.3 b/tests/witness/xml/xmlLayout.3 deleted file mode 100644 index 54e7239556..0000000000 --- a/tests/witness/xml/xmlLayout.3 +++ /dev/null @@ -1,5 +0,0 @@ - -hi]]>]]> - - - diff --git a/tests/witness/xml/xmlLayout.mdc.1 b/tests/witness/xml/xmlLayout.mdc.1 deleted file mode 100644 index 68cfb307e6..0000000000 --- a/tests/witness/xml/xmlLayout.mdc.1 +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/tests/witness/xml/xmlLayout.mdc.2 b/tests/witness/xml/xmlLayout.mdc.2 deleted file mode 100644 index de4d06fad2..0000000000 --- a/tests/witness/xml/xmlLayout.mdc.2 +++ /dev/null @@ -1,8 +0,0 @@ - - - - ]]>" value=""/> - ]]>"/> - - - diff --git a/tests/witness/xml/xmlLayout.null b/tests/witness/xml/xmlLayout.null deleted file mode 100644 index d2deb4ee8a..0000000000 --- a/tests/witness/xml/xmlLayout.null +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - diff --git a/tests/witness/xmlLayout.1 b/tests/witness/xmlLayout.1 new file mode 100644 index 0000000000..80e596846b --- /dev/null +++ b/tests/witness/xmlLayout.1 @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/witness/xmlLayout.2 b/tests/witness/xmlLayout.2 new file mode 100644 index 0000000000..a3e094b1ca --- /dev/null +++ b/tests/witness/xmlLayout.2 @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/witness/xmlLayout.3 b/tests/witness/xmlLayout.3 new file mode 100644 index 0000000000..2fa705f773 --- /dev/null +++ b/tests/witness/xmlLayout.3 @@ -0,0 +1,10 @@ + +hi]]>]]> + + + + +hi]]>]]> + + + diff --git a/tests/witness/xmlLayout.mdc.1 b/tests/witness/xmlLayout.mdc.1 new file mode 100644 index 0000000000..2dfe4ef8f7 --- /dev/null +++ b/tests/witness/xmlLayout.mdc.1 @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/witness/xmlLayout.mdc.2 b/tests/witness/xmlLayout.mdc.2 new file mode 100644 index 0000000000..d382c4c43f --- /dev/null +++ b/tests/witness/xmlLayout.mdc.2 @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/witness/xmlLayout.null b/tests/witness/xmlLayout.null new file mode 100644 index 0000000000..0ebcb33cd0 --- /dev/null +++ b/tests/witness/xmlLayout.null @@ -0,0 +1,23 @@ + + + + + + + + + + + + +