[maven-release-plugin] copy for tag v1_0_rc1
git-svn-id: https://svn.apache.org/repos/asf/logging/log4j/companions/receivers/tags/v1_0_rc1@551402 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/NOTICE b/NOTICE
index d8ce6d9..e5b57a8 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,4 +1,4 @@
-Apache log4j 1.3 receivers for log4j 1.2
+Apache Receivers Companion for log4j 1.2.
Copyright 2007 The Apache Software Foundation
This product includes software developed at
diff --git a/build.xml b/build.xml
index 639d13b..491da3d 100644
--- a/build.xml
+++ b/build.xml
@@ -21,6 +21,8 @@
This is a minimal build file to support Gump.
Use of Maven to build this component is recommended.
+Specify -Dcompanion.jar=foo.jar to test a previously prepared jar.
+
-->
<project default="test">
<!-- use build.properties file or command line to override these properties -->
@@ -29,7 +31,7 @@
<!-- project details -->
<property name="project.name" value="apache-log4j-receivers"/>
<property name="project.title" value="Apache Receivers Companion for log4j 1.2."/>
- <property name="project.version" value="0.1-SNAPSHOT"/>
+ <property name="project.version" value="1.0"/>
<property name="project.jar" value="${project.name}-${project.version}.jar"/>
<!-- Location of local Maven 2 repository -->
@@ -39,9 +41,10 @@
<property name="log4j.version" value="1.2.15"/>
<property name="junit.version" value="3.8.1"/>
<property name="oro.version" value="2.0.8"/>
- <property name="component.version" value="0.1-SNAPSHOT"/>
- <property name="filters.version" value="0.1-SNAPSHOT"/>
- <property name="javaee.version" value="5"/>
+ <property name="hsqldb.version" value="1.8.0.7"/>
+ <property name="component.version" value="1.0"/>
+ <property name="filters.version" value="1.0"/>
+ <property name="jms.version" value="1.1"/>
<!-- Dependency locations - assumed to be in Maven 2 repository -->
<property name="junit.jar"
@@ -54,12 +57,14 @@
location="${m2_repo}/log4j/apache-log4j-filters/${filters.version}/apache-log4j-filters-${filters.version}.jar"/>
<property name="oro.jar"
location="${m2_repo}/oro/oro/${oro.version}/oro-${oro.version}.jar"/>
- <property name="javaee.jar"
- location="${m2_repo}/javaee/javaee-api/${javaee.version}/javaee-api-${javaee.version}.jar"/>
+ <property name="jms.jar"
+ location="${m2_repo}/javax/jms/jms/${jms.version}/jms-${jms.version}.jar"/>
+ <property name="hsqldb.jar"
+ location="${m2_repo}/hsqldb/hsqldb/${hsqldb.version}/hsqldb-${hsqldb.version}.jar"/>
<!-- Java compiler settings -->
- <property name="javac.source" value="1.3"/>
- <property name="javac.target" value="1.2"/>
+ <property name="javac.source" value="1.2"/>
+ <property name="javac.target" value="1.1"/>
<property name="javac.deprecation" value="true"/>
<property name="javac.debug" value="true"/>
@@ -69,14 +74,7 @@
<delete dir="target"/>
</target>
- <path id="compile-classpath" path="${log4j.jar}:${oro.jar}:${component.jar}:${filters.jar}:${javaee.jar}"/>
- <path id="test-classpath">
- <path refid="compile-classpath"/>
- <pathelement location="target/classes"/>
- <pathelement location="${junit.jar}"/>
- </path>
-
- <target name="compile" depends="init" description="Compile implementation files">
+ <target name="compile" depends="init" unless="companion.jar" description="Compile implementation files">
<mkdir dir="target/classes"/>
<javac destdir="target/classes"
srcdir="src/main/java"
@@ -84,21 +82,18 @@
debug="${javac.debug}"
target="${javac.target}"
source="${javac.source}"
- classpathref="compile-classpath"/>
- <copy todir="target/classes">
+ classpath="${log4j.jar}:${oro.jar}:${component.jar}:${filters.jar}:${jms.jar}"/>
+ <copy todir="target/classes" overwrite="true">
<fileset dir="src/main/resources"/>
</copy>
</target>
- <target name="jar" depends="compile" description="Create jar">
+ <target name="jar" depends="compile" unless="companion.jar" description="Create jar">
<jar destfile="target/${project.jar}"
basedir="target/classes">
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<section name="common">
- <attribute name="Specification-Title" value="${project.title}"/>
- <attribute name="Specification-Version" value="${project.version}"/>
- <attribute name="Specification-Vendor" value="Apache Software Foundation"/>
<attribute name="Implementation-Title" value="${project.title}"/>
<attribute name="Implementation-Version" value="${project.version}"/>
<attribute name="Implementation-Vendor" value="Apache Software Foundation"/>
@@ -107,7 +102,8 @@
</jar>
</target>
- <target name="test-compile" depends="compile" description="Compile test files">
+ <target name="test-compile" depends="jar" description="Compile test files">
+ <property name="companion.jar" value="target/${project.jar}"/>
<mkdir dir="target/test-classes"/>
<javac destdir="target/test-classes"
srcdir="src/test/java"
@@ -115,8 +111,8 @@
debug="${javac.debug}"
target="${javac.target}"
source="${javac.source}"
- classpathref="test-classpath"/>
- <copy todir="target/test-classes">
+ classpath="${companion.jar}:${hsqldb.jar}:${junit.jar}:${log4j.jar}:${oro.jar}:${component.jar}:${filters.jar}:${jms.jar}"/>
+ <copy todir="target/test-classes" overwrite="true">
<fileset dir="src/test/resources"/>
</copy>
</target>
@@ -124,12 +120,10 @@
<target name="test" depends="test-compile" description="Run unit tests">
<junit printsummary="yes" fork="yes" dir="target">
- <classpath>
- <path refid="test-classpath"/>
- <pathelement path="target/test-classes"/>
- </classpath>
+ <classpath path="target/test-classes:${companion.jar}:${hsqldb.jar}:${junit.jar}:${log4j.jar}:${oro.jar}:${component.jar}:${filters.jar}:${jms.jar}"/>
<batchtest>
<fileset dir="src/test/java/">
+ <include name="**/Test*.java"/>
<include name="**/*TestCase.java"/>
<include name="**/*Test.java"/>
</fileset>
diff --git a/pom.xml b/pom.xml
index 027696a..2ba43db 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,19 +15,18 @@
limitations under the License.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>log4j</groupId>
<artifactId>apache-log4j-receivers</artifactId>
<packaging>jar</packaging>
- <version>0.1-SNAPSHOT</version>
+ <version>1.0</version>
<name>Apache Receivers Companion for log4j 1.2.</name>
<description>This companion provides a collection of receivers from the log4j 1.3 project for use with log4j 1.2.</description>
- <url>http://logging.apache.org/log4j/companions/receivers</url>
+ <url>http://logging.apache.org:80/log4j/companions/receivers</url>
<issueManagement>
<system>Bugzilla</system>
- <url>http://issues.apache.org/bugzilla</url>
+ <url>http://issues.apache.org/bugzilla/</url>
</issueManagement>
<ciManagement>
<system>Gump</system>
@@ -57,19 +56,6 @@
</otherArchives>
</mailingList>
</mailingLists>
-<developers>
- <developer>
- <id>carnold</id>
- <name>Curt Arnold</name>
- <email>carnold@apache.org</email>
- <timezone>-6</timezone>
- </developer>
- <developer>
- <id>psmith</id>
- <name>Paul Smith</name>
- <email>psmith@apache.org</email>
- </developer>
- </developers>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
@@ -78,9 +64,9 @@
</license>
</licenses>
<scm>
- <connection>scm:svn:http://svn.apache.org/repos/asf/logging/sandbox/log4j/receivers</connection>
- <developerConnection>scm:svn:https://svn.apache.org/repos/asf/logging/sandbox/log4j/receivers</developerConnection>
- <url>http://svn.apache.org/viewcvs.cgi/logging/sandbox/log4j/receivers</url>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/logging/log4j/companions/receivers/tags/v1_0_rc1</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/logging/log4j/companions/receivers/tags/v1_0_rc1</developerConnection>
+ <url>http://svn.apache.org/viewcvs.cgi/logging/log4j/companions/receivers/tags/v1_0_rc1</url>
</scm>
<organization>
<name>Apache Software Foundation</name>
@@ -89,44 +75,99 @@
<build>
<plugins>
<plugin>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <dependencies>
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>1.2.14</version>
- </dependency>
- </dependencies>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <workingDirectory>target</workingDirectory>
+ </configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
- <source>1.3</source>
- <target>1.3</target>
+ <source>1.2</source>
+ <target>1.1</target>
</configuration>
</plugin>
- <!-- clean stray cobertura.ser -->
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>cobertura-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>clean</id>
- <goals>
- <goal>clean</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestSections>
+ <manifestSection>
+ <name>org.apache.log4j</name>
+ <manifestEntries>
+ <Implementation-Title>${project.name}</Implementation-Title>
+ <Implementation-Version>${project.version}</Implementation-Version>
+ <Implementation-Vendor>Apache Software Foundation</Implementation-Vendor>
+ </manifestEntries>
+ </manifestSection>
+ </manifestSections>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>site</phase>
+ <id>untag-site</id>
+ <configuration>
+ <tasks>
+ <taskdef name="replaceregexp" classname="org.apache.tools.ant.taskdefs.optional.ReplaceRegExp" />
+ <replaceregexp file="target/site/source-repository.html" match="/tags/[^ ]*" replace="/trunk" flags="g" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>ant</groupId>
+ <artifactId>ant-nodeps</artifactId>
+ <version>1.6.5</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptors>
+ <descriptor>src/assembly/bin.xml</descriptor>
+ </descriptors>
+ <appendAssemblyId>false</appendAssemblyId>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>assembly</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>jar</goal>
+ <goal>javadoc</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
-<repositories>
- <repository>
- <id>java.net</id>
- <url>https://maven-repository.dev.java.net/nonav/repository</url>
- <layout>legacy</layout>
- </repository>
-</repositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
@@ -135,6 +176,12 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ <version>1.8.0.7</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
@@ -142,12 +189,12 @@
<dependency>
<groupId>log4j</groupId>
<artifactId>apache-log4j-component</artifactId>
- <version>0.1-SNAPSHOT</version>
+ <version>1.0</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>apache-log4j-filters</artifactId>
- <version>0.1-SNAPSHOT</version>
+ <version>1.0</version>
</dependency>
<dependency>
<groupId>oro</groupId>
@@ -155,38 +202,40 @@
<version>2.0.8</version>
</dependency>
<dependency>
- <groupId>javaee</groupId>
- <artifactId>javaee-api</artifactId>
- <version>5</version>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ <version>1.1</version>
</dependency>
</dependencies>
<reporting>
+ <excludeDefaults>true</excludeDefaults>
<plugins>
<plugin>
- <artifactId>maven-checkstyle-plugin</artifactId>
- </plugin>
- <plugin>
- <artifactId>maven-pmd-plugin</artifactId>
- </plugin>
- <plugin>
- <artifactId>maven-javadoc-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>scm</report>
+ <report>dependencies</report>
+ <report>cim</report>
+ <report>issue-tracking</report>
+ <report>mailing-list</report>
+ <report>license</report>
+ </reports>
+ </reportSet>
+ </reportSets>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jxr-maven-plugin</artifactId>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>cobertura-maven-plugin</artifactId>
- <!-- version 2.1 was flawed and reports 100% coverage -->
- <version>2.0</version>
- </plugin>
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ <configuration>
+ <goals>site-deploy</goals>
+ </configuration>
+ </plugin>
+ <plugin>
<artifactId>maven-changes-plugin</artifactId>
<reportSets>
<reportSet>
@@ -199,12 +248,22 @@
<issueLinkTemplate>%URL%/show_bug.cgi?id=%ISSUE%</issueLinkTemplate>
</configuration>
</plugin>
+ <plugin>
+ <artifactId>maven-pmd-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ </plugin>
</plugins>
</reporting>
<distributionManagement>
+ <repository>
+ <id>logging.repo</id>
+ <url>scp://people.apache.org/www/people.apache.org/builds/logging/repo/</url>
+ </repository>
<site>
- <id>apache.website</id>
- <url>scp://people.apache.org/home/carnold/public_html/log4j/companions/receivers</url>
+ <id>logging.site</id>
+ <url>scp://people.apache.org/www/logging.apache.org/log4j/companions/receivers</url>
</site>
</distributionManagement>
</project>
diff --git a/src/assembly/bin.xml b/src/assembly/bin.xml
new file mode 100644
index 0000000..d95088b
--- /dev/null
+++ b/src/assembly/bin.xml
@@ -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.
+
+-->
+<assembly>
+ <id>bin</id>
+ <formats>
+ <format>zip</format>
+ <format>tar.gz</format>
+ </formats>
+ <baseDirectory>apache-log4j-receivers-${project.version}</baseDirectory>
+ <includeSiteDirectory>true</includeSiteDirectory>
+ <fileSets>
+ <fileSet>
+ <includes>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ <include>build.xml</include>
+ <include>pom.xml</include>
+ <include>src/**</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>target</directory>
+ <outputDirectory>.</outputDirectory>
+ <includes>
+ <include>apache-log4j-receivers-${project.version}.jar</include>
+ </includes>
+ </fileSet>
+ </fileSets>
+
+</assembly>
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 8830e38..9541f25 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
Binary files differ
diff --git a/src/main/java/org/apache/log4j/db/CustomSQLDBReceiver.java b/src/main/java/org/apache/log4j/db/CustomSQLDBReceiver.java
index 9e0a9b8..16d9455 100644
--- a/src/main/java/org/apache/log4j/db/CustomSQLDBReceiver.java
+++ b/src/main/java/org/apache/log4j/db/CustomSQLDBReceiver.java
@@ -23,9 +23,12 @@
import java.sql.Statement;
import java.util.Hashtable;
import java.util.StringTokenizer;
+import java.util.Properties;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
+import org.apache.log4j.xml.UnrecognizedElementHandler;
+import org.apache.log4j.xml.DOMConfigurator;
import org.apache.log4j.plugins.Pauseable;
import org.apache.log4j.plugins.Receiver;
import org.apache.log4j.scheduler.Job;
@@ -34,6 +37,8 @@
import org.apache.log4j.spi.LoggerRepositoryEx;
import org.apache.log4j.spi.ThrowableInformation;
import org.apache.log4j.spi.LocationInfo;
+import org.apache.log4j.spi.OptionHandler;
+import org.w3c.dom.Element;
/**
* Converts log data stored in a database into LoggingEvents.
@@ -126,7 +131,7 @@
* @author Scott Deboy <sdeboy@apache.org>
* <p>
*/
-public class CustomSQLDBReceiver extends Receiver implements Pauseable {
+public class CustomSQLDBReceiver extends Receiver implements Pauseable, UnrecognizedElementHandler {
protected volatile Connection connection = null;
@@ -444,4 +449,22 @@
}
}
}
+
+ /**
+ * @{inheritDoc}
+ */
+ public boolean parseUnrecognizedElement(Element element, Properties props) throws Exception {
+ if ("connectionSource".equals(element.getNodeName())) {
+ Object instance =
+ DOMConfigurator.parseElement(element, props, ConnectionSource.class);
+ if (instance instanceof ConnectionSource) {
+ ConnectionSource source = (ConnectionSource) instance;
+ source.activateOptions();
+ setConnectionSource(source);
+ }
+ return true;
+ }
+ return false;
+ }
+
}
diff --git a/src/main/java/org/apache/log4j/db/DBAppender.java b/src/main/java/org/apache/log4j/db/DBAppender.java
index e8bbf5d..f463fa3 100644
--- a/src/main/java/org/apache/log4j/db/DBAppender.java
+++ b/src/main/java/org/apache/log4j/db/DBAppender.java
@@ -21,18 +21,22 @@
import org.apache.log4j.db.dialect.SQLDialect;
import org.apache.log4j.db.dialect.Util;
import org.apache.log4j.helpers.LogLog;
-import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.LocationInfo;
+import org.apache.log4j.spi.LoggingEvent;
+import org.apache.log4j.xml.DOMConfigurator;
+import org.apache.log4j.xml.UnrecognizedElementHandler;
+import org.w3c.dom.Element;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
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.Properties;
import java.util.Set;
-import java.lang.reflect.*;
/**
@@ -106,14 +110,14 @@
*
* <p>
* <b>Configuration </b> DBAppender can be configured programmatically, or using
- * {@link org.apache.log4j.joran.JoranConfigurator JoranConfigurator}. Example
+ * {@link org.apache.log4j.xml.DOMConfigurator JoranConfigurator}. Example
* scripts can be found in the <em>tests/input/db</em> directory.
*
* @author Ceki Gülcü
* @author Ray DeCampo
* @since 1.3
*/
-public class DBAppender extends AppenderSkeleton {
+public class DBAppender extends AppenderSkeleton implements UnrecognizedElementHandler {
static final String insertPropertiesSQL =
"INSERT INTO logging_event_property (event_id, mapped_key, mapped_value) VALUES (?, ?, ?)";
static final String insertExceptionSQL =
@@ -163,7 +167,7 @@
}
public void activateOptions() {
- getLogger().debug("DBAppender.activateOptions called");
+ LogLog.debug("DBAppender.activateOptions called");
if (connectionSource == null) {
throw new IllegalStateException(
@@ -198,7 +202,7 @@
* The connectionSource to set.
*/
public void setConnectionSource(ConnectionSource connectionSource) {
- getLogger().debug("setConnectionSource called for DBAppender");
+ LogLog.debug("setConnectionSource called for DBAppender");
this.connectionSource = connectionSource;
}
@@ -237,7 +241,7 @@
int updateCount = insertStatement.executeUpdate();
if (updateCount != 1) {
- getLogger().warn("Failed to insert loggingEvent");
+ LogLog.warn("Failed to insert loggingEvent");
}
ResultSet rs = null;
@@ -254,7 +258,7 @@
}
throw ex;
} catch(IllegalAccessException ex) {
- getLogger().warn("IllegalAccessException invoking PreparedStatement.getGeneratedKeys", ex);
+ LogLog.warn("IllegalAccessException invoking PreparedStatement.getGeneratedKeys", ex);
}
}
@@ -318,7 +322,7 @@
String[] strRep = event.getThrowableStrRep();
if (strRep != null) {
- getLogger().debug("Logging an exception");
+ LogLog.debug("Logging an exception");
PreparedStatement insertExceptionStatement =
connection.prepareStatement(insertExceptionSQL);
@@ -342,7 +346,7 @@
connection.commit();
} catch (Throwable sqle) {
- getLogger().error("problem appending event", sqle);
+ LogLog.error("problem appending event", sqle);
} finally {
DBHelper.closeConnection(connection);
}
@@ -377,30 +381,20 @@
return false;
}
- /** Here Be Dragons.
- * This code is necessary because this class originally came from the log4j 1.3 area, before being backported to 1.3
- * In 1.3, Appenders had their own logger, but 1.2 does not have this, so instead we embed a 'compatible' mechanism here
- * The goal was to keep the code as similar as possible, to avoid as many conflicts as possble.
- * Code suggested by Curt Arnold (and not Curty Arnold... ;) )
- */
-
- private static final class LogLogger {
- public void debug(final String msg) {
- LogLog.debug(msg);
+ /**
+ * @{inheritDoc}
+ */
+ public boolean parseUnrecognizedElement(Element element, Properties props) throws Exception {
+ if ("connectionSource".equals(element.getNodeName())) {
+ Object instance =
+ DOMConfigurator.parseElement(element, props, ConnectionSource.class);
+ if (instance instanceof ConnectionSource) {
+ ConnectionSource source = (ConnectionSource) instance;
+ source.activateOptions();
+ setConnectionSource(source);
+ }
+ return true;
}
- public void warn(final String msg, final Throwable ex) {
- LogLog.warn(msg, ex);
- }
- public void warn(final String msg) {
- LogLog.warn(msg);
- }
- public void error(final String msg, final Throwable ex) {
- LogLog.error(msg, ex);
- }
+ return false;
}
-
- private static final LogLogger getLogger() {
- return new LogLogger();
- }
-
}
diff --git a/src/main/java/org/apache/log4j/db/DBReceiver.java b/src/main/java/org/apache/log4j/db/DBReceiver.java
index 69effde..eee1068 100644
--- a/src/main/java/org/apache/log4j/db/DBReceiver.java
+++ b/src/main/java/org/apache/log4j/db/DBReceiver.java
@@ -20,8 +20,12 @@
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;
+import org.apache.log4j.xml.DOMConfigurator;
+import org.apache.log4j.xml.UnrecognizedElementHandler;
+import org.w3c.dom.Element;
+
+import java.util.Properties;
/**
*
@@ -29,7 +33,7 @@
* @author Ceki Gülcü
*
*/
-public class DBReceiver extends Receiver implements Pauseable {
+public class DBReceiver extends Receiver implements Pauseable, UnrecognizedElementHandler {
/**
* By default we refresh data every 1000 milliseconds.
* @see #setRefreshMillis
@@ -115,4 +119,22 @@
public boolean isPaused() {
return paused;
}
+
+ /**
+ * @{inheritDoc}
+ */
+ public boolean parseUnrecognizedElement(Element element, Properties props) throws Exception {
+ if ("connectionSource".equals(element.getNodeName())) {
+ Object instance =
+ DOMConfigurator.parseElement(element, props, ConnectionSource.class);
+ if (instance instanceof ConnectionSource) {
+ ConnectionSource source = (ConnectionSource) instance;
+ source.activateOptions();
+ setConnectionSource(source);
+ }
+ return true;
+ }
+ return false;
+ }
+
}
diff --git a/src/main/java/org/apache/log4j/db/DBReceiverJob.java b/src/main/java/org/apache/log4j/db/DBReceiverJob.java
index 2f2b24c..1e29663 100644
--- a/src/main/java/org/apache/log4j/db/DBReceiverJob.java
+++ b/src/main/java/org/apache/log4j/db/DBReceiverJob.java
@@ -21,16 +21,14 @@
import org.apache.log4j.Logger;
import org.apache.log4j.scheduler.Job;
import org.apache.log4j.spi.ComponentBase;
-import org.apache.log4j.spi.LoggerRepository;
+import org.apache.log4j.spi.LocationInfo;
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.Hashtable;
import java.util.Vector;
@@ -54,7 +52,7 @@
"WHERE event_id > ? ORDER BY event_id ASC";
- long lastId = 0;
+ long lastId = Short.MIN_VALUE;
DBReceiver parentDBReceiver;
@@ -197,7 +195,6 @@
*
* @param connection
* @param id
- * @param event
* @throws SQLException
*/
ThrowableInformation getException(Connection connection, long id)
diff --git a/src/main/java/org/apache/log4j/db/DataSourceConnectionSource.java b/src/main/java/org/apache/log4j/db/DataSourceConnectionSource.java
index 1994bd0..d5975ee 100644
--- a/src/main/java/org/apache/log4j/db/DataSourceConnectionSource.java
+++ b/src/main/java/org/apache/log4j/db/DataSourceConnectionSource.java
@@ -18,10 +18,14 @@
package org.apache.log4j.db;
-import java.sql.Connection;
-import java.sql.SQLException;
+import org.apache.log4j.xml.DOMConfigurator;
+import org.apache.log4j.xml.UnrecognizedElementHandler;
+import org.w3c.dom.Element;
import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
/**
@@ -33,7 +37,8 @@
* @author Ray DeCampo
* @author Ceki Gülcü
*/
-public class DataSourceConnectionSource extends ConnectionSourceSkeleton {
+public class DataSourceConnectionSource extends ConnectionSourceSkeleton
+ implements UnrecognizedElementHandler {
private DataSource dataSource;
@@ -82,5 +87,19 @@
this.dataSource = dataSource;
}
+ /**
+ * @{inheritDoc}
+ */
+ public boolean parseUnrecognizedElement(Element element, Properties props) throws Exception {
+ if ("dataSource".equals(element.getNodeName())) {
+ Object instance =
+ DOMConfigurator.parseElement(element, props, DataSource.class);
+ if (instance instanceof DataSource) {
+ setDataSource((DataSource) instance);
+ }
+ return true;
+ }
+ return false;
+ }
}
diff --git a/src/main/java/org/apache/log4j/net/MulticastAppender.java b/src/main/java/org/apache/log4j/net/MulticastAppender.java
new file mode 100644
index 0000000..0334aa4
--- /dev/null
+++ b/src/main/java/org/apache/log4j/net/MulticastAppender.java
@@ -0,0 +1,310 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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;
+import org.apache.log4j.helpers.LogLog;
+
+
+/**
+ * Multicast-based Appender. Works in conjunction with the MulticastReceiver, which expects
+ * a LoggingEvent encoded using XMLLayout.
+ *
+ * Sends log information as a multicast datagrams.
+ *
+ * <p>Messages are not sent as LoggingEvent objects but as text after
+ * applying XMLLayout.
+ *
+ * <p>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.
+ *
+ * <p>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 <a href="mailto:kbrown@versatilesolutions.com">Kevin Brown</a>
+ * @author Scott Deboy <sdeboy@apache.org>
+ *
+ */
+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 <b>RemoteHost</b> and <b>Port</b>.
+ */
+ 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;
+ LogLog.error(err);
+ throw new IllegalStateException(err);
+ }
+
+ connect();
+ super.activateOptions();
+ }
+
+ /**
+ Close this appender.
+ <p>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) {
+ LogLog.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) {
+ LogLog.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;
+ LogLog.warn("Detected problem with Multicast connection: " + e);
+ }
+ }
+ }
+
+ InetAddress getAddressByName(String host) {
+ try {
+ return InetAddress.getByName(host);
+ } catch (Exception e) {
+ LogLog.error("Could not find address of [" + host + "].", e);
+ return null;
+ }
+ }
+
+ /**
+ The <b>RemoteHost</b> 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 <b>RemoteHost</b> option.
+ */
+ public String getRemoteHost() {
+ return remoteHost;
+ }
+
+ /**
+ The <b>Encoding</b> 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 <b>Encoding</b> option.
+ */
+ public String getEncoding() {
+ return encoding;
+ }
+ /**
+ The <b>App</b> 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 <b>App</b> option.
+ */
+ public String getApplication() {
+ return application;
+ }
+
+ /**
+ The <b>OverrideProperties</b> 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 <b>OverrideProperties</b> option.
+ */
+ public String getOverrideProperties() {
+ return overrideProperties;
+ }
+
+ /**
+ The <b>Time to live</b> option takes a positive integer representing
+ the time to live value.
+ */
+ public void setTimeToLive(int timeToLive) {
+ this.timeToLive = timeToLive;
+ }
+
+ /**
+ Returns value of the <b>Time to Live</b> option.
+ */
+ public int getTimeToLive() {
+ return timeToLive;
+ }
+
+ /**
+ The <b>Port</b> 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 <b>Port</b> 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/SocketHubReceiver.java b/src/main/java/org/apache/log4j/net/SocketHubReceiver.java
index f341d58..2032fb9 100644
--- a/src/main/java/org/apache/log4j/net/SocketHubReceiver.java
+++ b/src/main/java/org/apache/log4j/net/SocketHubReceiver.java
@@ -17,23 +17,16 @@
package org.apache.log4j.net;
+import org.apache.log4j.plugins.Plugin;
+import org.apache.log4j.plugins.Receiver;
+import org.apache.log4j.spi.LoggerRepository;
+
import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.BufferedInputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-import java.lang.reflect.Method;
-
-import org.apache.log4j.plugins.Plugin;
-import org.apache.log4j.plugins.Receiver;
-import org.apache.log4j.plugins.Pauseable;
-import org.apache.log4j.spi.LoggerRepository;
-import org.apache.log4j.spi.ComponentBase;
-import org.apache.log4j.spi.LoggingEvent;
-import org.apache.log4j.Logger;
/**
SocketHubReceiver receives a remote logging event on a configured
diff --git a/src/main/java/org/apache/log4j/net/UDPAppender.java b/src/main/java/org/apache/log4j/net/UDPAppender.java
new file mode 100644
index 0000000..e03ec57
--- /dev/null
+++ b/src/main/java/org/apache/log4j/net/UDPAppender.java
@@ -0,0 +1,327 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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.AppenderSkeleton;
+import org.apache.log4j.helpers.Constants;
+import org.apache.log4j.spi.LoggingEvent;
+import org.apache.log4j.helpers.LogLog;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+
+
+/**
+ * Sends log information as a UDP datagrams.
+ *
+ * <p>The UDPAppender is meant to be used as a diagnostic logging tool
+ * so that logging can be monitored by a simple UDP client.
+ *
+ * <p>Messages are not sent as LoggingEvent objects but as text after
+ * applying the designated Layout.
+ *
+ * <p>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.
+ *
+ * <p>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 <a href="mailto:kbrown@versatilesolutions.com">Kevin Brown</a>
+ * @author Scott Deboy <sdeboy@apache.org>
+ */
+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 <code>address</code> and <code>port</code>.
+ */
+ 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 <code>address</code> and <code>port</code>.
+ */
+ 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 <b>RemoteHost</b> and <b>Port</b>.
+ */
+ 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;
+ LogLog.error(err);
+ throw new IllegalStateException(err);
+ }
+ super.activateOptions();
+ }
+
+ /**
+ Close this appender.
+ <p>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) {
+ LogLog.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) {
+ LogLog.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;
+ LogLog.warn("Detected problem with UDP connection: " + e);
+ }
+ }
+ }
+
+ public boolean isActive() {
+ return !inError;
+ }
+
+ InetAddress getAddressByName(String host) {
+ try {
+ return InetAddress.getByName(host);
+ } catch (Exception e) {
+ LogLog.error("Could not find address of [" + host + "].", e);
+ return null;
+ }
+ }
+
+ /**
+ The UDPAppender uses layouts. Hence, this method returns
+ <code>true</code>.
+ */
+ public boolean requiresLayout() {
+ return true;
+ }
+
+ /**
+ The <b>RemoteHost</b> 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 <b>RemoteHost</b> option.
+ */
+ public String getRemoteHost() {
+ return remoteHost;
+ }
+
+ /**
+ The <b>App</b> 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 <b>App</b> option.
+ */
+ public String getApplication() {
+ return application;
+ }
+
+ /**
+ The <b>Encoding</b> 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 <b>Encoding</b> option.
+ */
+ public String getEncoding() {
+ return encoding;
+ }
+
+ /**
+ The <b>OverrideProperties</b> 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 <b>OverrideProperties</b> option.
+ */
+ public String getOverrideProperties() {
+ return overrideProperties;
+ }
+
+ /**
+ The <b>Port</b> 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 <b>Port</b> option.
+ */
+ public int getPort() {
+ return port;
+ }
+
+}
diff --git a/src/main/java/org/apache/log4j/xml/LogFileXMLReceiver.java b/src/main/java/org/apache/log4j/xml/LogFileXMLReceiver.java
new file mode 100644
index 0000000..3109df7
--- /dev/null
+++ b/src/main/java/org/apache/log4j/xml/LogFileXMLReceiver.java
@@ -0,0 +1,287 @@
+/*
+ * 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.
+
+<p>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).
+
+<p>By default, log4j's XMLLayout is supported (no need to specify a decoder in that case).
+
+<p>To configure this receiver to support java.util.logging's XMLFormatter, specify a
+'decoder' param of org.apache.log4j.xml.UtilLoggingXMLDecoder.
+
+<p>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.
+
+<p>An expressionFilter may be specified. Only events passing the expression will be forwarded to the log4j framework.
+
+<p>Once the event has been "posted", it will be handled by the
+appenders currently configured in the LoggerRespository.
+
+@author Scott Deboy <sdeboy@apache.org>
+
+ @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/resources/META-INF/NOTICE b/src/main/resources/META-INF/NOTICE
index d8ce6d9..e5b57a8 100644
--- a/src/main/resources/META-INF/NOTICE
+++ b/src/main/resources/META-INF/NOTICE
@@ -1,4 +1,4 @@
-Apache log4j 1.3 receivers for log4j 1.2
+Apache Receivers Companion for log4j 1.2.
Copyright 2007 The Apache Software Foundation
This product includes software developed at
diff --git a/src/site/apt/download.apt b/src/site/apt/download.apt
new file mode 100644
index 0000000..ee19d8e
--- /dev/null
+++ b/src/site/apt/download.apt
@@ -0,0 +1,39 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one or more
+~~ contributor license agreements. See the NOTICE file distributed with
+~~ this work for additional information regarding copyright ownership.
+~~ The ASF licenses this file to You under the Apache License, Version 2.0
+~~ (the "License"); you may not use this file except in compliance with
+~~ the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing, software
+~~ distributed under the License is distributed on an "AS IS" BASIS,
+~~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~~ See the License for the specific language governing permissions and
+~~ limitations under the License.
+ ------
+Download apache-log4j-receivers
+ ------
+ ------
+ ------
+
+Download apache-log4j-receivers
+
+ Apache Receivers Companion for log4j 1.2 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,
+ try a different browser. The checksum and signature are links to
+ the originals on the main distribution server.
+
+*-------------------------+---------+----------+-----------+
+| | Mirrors | Checksum | Signature |
+*-------------------------+---------+----------+-----------+
+| apache-log4j-receivers-1.0 (tar.gz) | {{{http://www.apache.org/dyn/closer.cgi/logging/log4j/companions/receivers/1.0/apache-log4j-receivers-1.0.tar.gz} apache-log4j-receivers-1.0.tar.gz}} | {{{http://www.apache.org/dist/logging/log4j/companions/receivers/1.0/apache-log4j-receivers-1.0.tar.gz.md5} apache-log4j-receivers-1.0.tar.gz.md5}} | {{{http://www.apache.org/dist/logging/log4j/companions/receivers/1.0/apache-log4j-receivers-1.0.tar.gz.asc} apache-log4j-receivers-1.0.tar.gz.asc}} |
+*-------------------------+---------+----------+-----------+
+| apache-log4j-receivers-1.0 (zip) | {{{http://www.apache.org/dyn/closer.cgi/logging/log4j/companions/receivers/1.0/apache-log4j-receivers-1.0.zip} apache-log4j-receivers-1.0.zip}} | {{{http://www.apache.org/dist/logging/log4j/companions/receivers/1.0/apache-log4j-receivers-1.0.zip.md5} apache-log4j-receivers-1.0.zip.md5}} | {{{http://www.apache.org/dist/logging/log4j/companions/receivers/1.0/apache-log4j-receivers-1.0.zip.asc} apache-log4j-receivers-1.0.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.
diff --git a/src/site/apt/index.apt b/src/site/apt/index.apt
new file mode 100644
index 0000000..38dafbb
--- /dev/null
+++ b/src/site/apt/index.apt
@@ -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.
+ ------
+ Apache Receivers Companion for log4j 1.2
+ ------
+ ------
+ ------
+
+ This companion provides a collection of receivers from the log4j 1.3 project for use with log4j 1.2.
+
diff --git a/src/site/apt/roadmap.apt b/src/site/apt/roadmap.apt
new file mode 100644
index 0000000..fde38a5
--- /dev/null
+++ b/src/site/apt/roadmap.apt
@@ -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.
+ ------
+ apache-log4j-receivers Roadmap
+ ------
+ Curt Arnold
+ ------
+ 4 June 2007
+ ------
+
+apache-log4j-receivers Roadmap
+
+ No additional development is anticipated.
diff --git a/src/site/site.xml b/src/site/site.xml
index d627d75..9decb5e 100644
--- a/src/site/site.xml
+++ b/src/site/site.xml
@@ -15,22 +15,50 @@
limitations under the License.
-->
-<project name="Component">
+<project name="Receivers">
<bannerLeft>
<name>Logging Services</name>
<src>images/ls-logo.jpg</src>
<href>http://logging.apache.org/</href>
</bannerLeft>
<bannerRight>
+ <name>Apache log4j</name>
<src>images/logo.jpg</src>
+ <href>http://logging.apache.org/log4j</href>
</bannerRight>
<body>
- <links>
- <item name="Apache" href="http://www.apache.org/" />
+ <breadcrumbs>
+ <item name="Apache" href="http://www.apache.org/"/>
<item name="Logging Services" href="http://logging.apache.org/"/>
- <item name="Log4j" href="http://logging.apache.org/log4j/"/>
- <item name="Log4j Companions" href="http://logging.apache.org/log4j/companions"/>
- </links>
- <menu ref="reports"/>
+ <item name="log4j" href="http://logging.apache.org/log4j/"/>
+ <item name="Companions" href="http://logging.apache.org/log4j/companions/"/>
+ <item name="receivers" href="http://logging.apache.org:80/log4j/companions/receivers/"/>
+ </breadcrumbs>
+
+ <menu name="Get receivers">
+ <item name="Download" href="/download.html"/>
+ <item name="Changes" href="/changes-report.html"/>
+ <item name="License" href="/license.html"/>
+ </menu>
+
+ <menu name="About receivers">
+ <item name="What is it?" href="/index.html"/>
+ <item name="Roadmap" href="/roadmap.html"/>
+ <item name="JavaDoc" href="/apidocs/index.html"/>
+ </menu>
+
+ <menu name="Community">
+ <item name="Mailing Lists" href="/mail-lists.html"/>
+ <item name="Issue Tracking" href="/issue-tracking.html"/>
+ </menu>
+
+ <menu name="Development">
+ <item name="Repository" href="/source-repository.html"/>
+ <item name="Cross Reference" href="/jxr.html"/>
+ <item name="Dependencies" href="/dependencies.html"/>
+ <item name="Continuous Integration" href="/integration.html"/>
+ <item name="Duplication" href="/cpd.html"/>
+ <item name="PMD" href="/pmd.html"/>
+ </menu>
</body>
</project>
diff --git a/src/test/java/org/apache/log4j/VectorAppender.java b/src/test/java/org/apache/log4j/VectorAppender.java
new file mode 100644
index 0000000..d7833a8
--- /dev/null
+++ b/src/test/java/org/apache/log4j/VectorAppender.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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.util.Vector;
+import org.apache.log4j.spi.LoggingEvent;
+
+/**
+ An appender that appends logging events to a vector.
+ @author Ceki Gülcü
+*/
+public class VectorAppender extends AppenderSkeleton {
+ public Vector vector;
+
+ long delay = 0;
+
+ public VectorAppender() {
+ super(true);
+ vector = new Vector();
+ }
+
+
+ /**
+ This method is called by the {@link AppenderSkeleton#doAppend}
+ method.
+
+ */
+ public void append(LoggingEvent event) {
+ if(delay > 0) {
+ try {
+ Thread.sleep(delay);
+ } 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;
+ }
+
+ this.closed = true;
+ }
+
+ public boolean isClosed() {
+ return closed;
+ }
+
+ 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/src/test/java/org/apache/log4j/db/FullCycleDBTest.java b/src/test/java/org/apache/log4j/db/FullCycleDBTest.java
new file mode 100644
index 0000000..6352974
--- /dev/null
+++ b/src/test/java/org/apache/log4j/db/FullCycleDBTest.java
@@ -0,0 +1,327 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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 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.LoggerRepositoryExImpl;
+import org.apache.log4j.helpers.Constants;
+import org.apache.log4j.xml.DOMConfigurator;
+import org.apache.log4j.spi.LocationInfo;
+import org.apache.log4j.spi.LoggingEvent;
+import org.apache.log4j.spi.RootLogger;
+import org.apache.log4j.spi.LoggerRepository;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Vector;
+import java.util.HashMap;
+import java.io.InputStream;
+import java.io.IOException;
+
+
+/**
+ * This test case writes a few events into a databases and reads them
+ * back comparing the event written and read back.
+ *
+ * <p>It relies heavily on the proper configuration of its environment
+ * in joran config files as well system properties.
+ * </p>
+ *
+ * <p>See also the Ant build file in the tests/ directory.</p>
+ *
+ * @author Ceki Gülcü
+ */
+public class FullCycleDBTest
+ extends TestCase {
+
+ Vector witnessEvents;
+ Hierarchy lrWrite;
+ LoggerRepository lrRead;
+ String appendConfigFile = null;
+ String readConfigFile = null;
+
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp()
+ throws Exception {
+ super.setUp();
+ appendConfigFile = "append-with-drivermanager1.xml";
+ readConfigFile = "read-with-drivermanager1.xml";
+
+ witnessEvents = new Vector();
+ lrWrite = new Hierarchy(new RootLogger(Level.DEBUG));
+ lrRead = new LoggerRepositoryExImpl(new Hierarchy(new RootLogger(Level.DEBUG)));
+
+
+ //
+ // attempt to define tables in in-memory database
+ // will throw exception if already defined.
+ //
+ Class.forName("org.hsqldb.jdbcDriver");
+ Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:testdb");
+ try {
+ Statement s = connection.createStatement();
+ s.executeUpdate("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)");
+ s.executeUpdate("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))");
+ s.executeUpdate("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))");
+ } catch(SQLException ex) {
+ String s = ex.toString();
+ } finally {
+ connection.close();
+ }
+
+ }
+
+
+ /*
+ * @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 {
+ DOMConfigurator jc1 = new DOMConfigurator();
+ InputStream is = FullCycleDBTest.class.getResourceAsStream(appendConfigFile);
+ jc1.doConfigure(is, lrWrite);
+ is.close();
+
+ 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() throws IOException {
+ DOMConfigurator jc1 = new DOMConfigurator();
+ InputStream is = FullCycleDBTest.class.getResourceAsStream(appendConfigFile);
+ jc1.doConfigure(is, lrWrite);
+ is.close();
+
+ long startTime = System.currentTimeMillis();
+
+ // Write out just one log message
+ MDC.put("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);
+
+ 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.remove("key1");
+ MDC.remove("key2");
+ MDC.remove("key3");
+
+ 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) throws IOException {
+ DOMConfigurator jc2 = new DOMConfigurator();
+ InputStream is = FullCycleDBTest.class.getResourceAsStream(configfile);
+ jc2.doConfigure(is, lrRead);
+ is.close();
+
+ // 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.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");
+ }
+
+ Map sourceMap = re.getProperties();
+ Map remap;
+ if (sourceMap == null) {
+ remap = new HashMap();
+ } else {
+ remap = new HashMap(sourceMap);
+ if (remap.containsKey(Constants.LOG4J_ID_KEY)) {
+ remap.remove(Constants.LOG4J_ID_KEY);
+ }
+ }
+ if(le.getProperties() == null || le.getProperties().size() == 0) {
+ if(remap.size() != 0) {
+ System.out.println("properties are "+remap);
+ fail("Returned event should have been empty");
+ }
+ } else {
+ assertEquals(le.getProperties(), remap);
+ }
+ 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().fullInfo, r.getLocationInformation().fullInfo);
+ } 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/src/test/resources/org/apache/log4j/db/append-with-drivermanager1.xml b/src/test/resources/org/apache/log4j/db/append-with-drivermanager1.xml
new file mode 100644
index 0000000..04d02bd
--- /dev/null
+++ b/src/test/resources/org/apache/log4j/db/append-with-drivermanager1.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<!DOCTYPE log4j:configuration SYSTEM 'http://logging.apache.org/log4j/1.2/log4j.dtd'>
+
+<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/' debug="true">
+
+ <appender name="DB" class="org.apache.log4j.db.DBAppender">
+ <param name="locationInfo" value="true"/>
+ <connectionSource class="org.apache.log4j.db.DriverManagerConnectionSource">
+ <param name="driverClass" value="org.hsqldb.jdbcDriver"/>
+ <param name="url" value="jdbc:hsqldb:mem:testdb"/>
+ <param name="user" value="sa"/>
+ <param name="password" value=""/>
+ </connectionSource>
+ </appender>
+
+ <appender name="VECTOR" class="org.apache.log4j.VectorAppender">
+ </appender>
+
+ <!-- Prevent internal log4j DEBUG messages from polluting the output. -->
+ <logger name="org.apache.log4j.joran"><level value="INFO" /></logger>
+ <logger name="org.apache.log4j.config"><level value="INFO" /></logger>
+ <logger name="org.apache.log4j.db.DBAppender"><level value="INFO" /></logger>
+
+ <root>
+ <level value ="debug"/>
+ <appender-ref ref="DB" />
+ <appender-ref ref="VECTOR" />
+ </root>
+</log4j:configuration>
+
+
diff --git a/src/test/resources/org/apache/log4j/db/read-with-drivermanager1.xml b/src/test/resources/org/apache/log4j/db/read-with-drivermanager1.xml
new file mode 100644
index 0000000..3e77c49
--- /dev/null
+++ b/src/test/resources/org/apache/log4j/db/read-with-drivermanager1.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<!DOCTYPE log4j:configuration SYSTEM 'http://logging.apache.org/log4j/1.2/log4j.dtd'>
+
+<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/' debug="true">
+
+ <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="READING %relative %level %logger - %message%n"/>
+ </layout>
+ </appender>
+
+ <appender name="VECTOR" class="org.apache.log4j.VectorAppender">
+ </appender>
+
+ <plugin name="DB" class="org.apache.log4j.db.DBReceiver">
+ <connectionSource class="org.apache.log4j.db.DriverManagerConnectionSource">
+ <param name="driverClass" value="org.hsqldb.jdbcDriver"/>
+ <param name="url" value="jdbc:hsqldb:mem:testdb"/>
+ <param name="user" value="sa"/>
+ <param name="password" value=""/>
+ </connectionSource>
+ </plugin>
+
+
+ <!-- Prevent internal log4j DEBUG messages from polluting the output. -->
+ <logger name="org.apache.log4j.joran"><level value="INFO" /></logger>
+ <logger name="org.apache.log4j.config"><level value="INFO" /></logger>
+ <logger name="org.apache.log4j.db"><level value="INFO" /></logger>
+
+ <root>
+ <level value="debug"/>
+ <appender-ref ref="VECTOR" />
+ <appender-ref ref="CONSOLE" />
+ </root>
+</log4j:configuration>
+
+
+