Author: carnold Date: Mon Dec 5 16:15:02 2005 New Revision: 354238 URL: http://svn.apache.org/viewcvs?rev=354238&view=rev Log: Bug 37762: RSSAppender contribution from Lara DAbreo
Added: logging/sandbox/log4j/contribs/trunk/LaraDAbreo/ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/ (with props) logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/build.properties.sample logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/build.xml logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/empty.xml logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/garbage.xml logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/readme.txt logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/rss.xml logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/FeedWriter.java logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/FilterWriter.java logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSAppender.java logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSEntry.java logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSEntryMapper.java logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSEntryMapperImpl.java logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/test/ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/test/TestRSSAppender.java logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/test/TestTailSeek.java logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/test/log.properties Propchange: logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Mon Dec 5 16:15:02 2005 @@ -0,0 +1,4 @@ +build +build.properties +.project +.classpath Added: logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/build.properties.sample URL: http://svn.apache.org/viewcvs/logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/build.properties.sample?rev=354238&view=auto ============================================================================== --- logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/build.properties.sample (added) +++ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/build.properties.sample Mon Dec 5 16:15:02 2005 @@ -0,0 +1,29 @@ +# Copyright 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. +# +lib.home.dir=/usr/share/java/ +#log4j available from http://logging.apache.org +log4j.lib.dir=${lib.home.dir} +log4j.version=1.3alpha-7 +log4j.jar=${log4j.lib.dir}/log4j-${log4j.version}.jar +# ROME available from http://rome.dev.java.net +rome.lib.dir=${lib.home.dir} +rome.version=0.6 +rome.jar=${rome.lib.dir}/rome-${rome.version}.jar +# JDOM available from http://www.jdom.org +jdom.lib.dir=${lib.home.dir} +jdom.jar=${jdom.lib.dir}/jdom.jar +# JUnit available from http://www.junit.org +junit.lib.dir=${lib.home.dir} +junit.jar=${junit.lib.dir}/junit.jar \ No newline at end of file Added: logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/build.xml URL: http://svn.apache.org/viewcvs/logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/build.xml?rev=354238&view=auto ============================================================================== --- logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/build.xml (added) +++ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/build.xml Mon Dec 5 16:15:02 2005 @@ -0,0 +1,200 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- + Copyright 2002, 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. + +--> +<project name="rssappender" default="run.tests" basedir="." > + + + <!-- The build.properties file defines the path to local jar files --> + <property file="build.properties"/> + + <property name="target" value="1.2"/> + <property name="source" value="1.3"/> + + + <property name="build.dir" value="build"/> + + <!-- Deprecation warning? --> + <property name="deprecation" value="on"/> + + <!-- Destination for compiled files --> + <property name="javac.dest" value="${build.dir}/classes"/> + <property name="javadoc.dest" value="${build.dir}/docs"/> + <property name="log4j-rss.jar" value="${build.dir}/log4j-rss.jar"/> + <property name="rssappender.classes" value="${javac.dest}"/> + <property name="tests.source.home" value="test"/> + + + + <!-- Construct compile classpath --> + <path id="compile.classpath"> + <pathelement location="${log4j.jar}"/> + <pathelement location="${rome.jar}"/> + <pathelement location="${jdom.jar}"/> + </path> + + <!-- Construct compile classpath --> + <path id="tests.classpath"> + <pathelement location="${rssappender.classes}"/> + <pathelement location="${junit.jar}"/> + <pathelement location="${log4j.jar}"/> + <pathelement location="${rome.jar}"/> + <pathelement location="${jdom.jar}"/> + <pathelement location="test"/> + </path> + + + <!-- ================================================================= --> + <!-- Default target --> + <!-- ================================================================= --> + + <target name="usage"> + <echo> + build - compile all project files + jar - build all jar files + run.tests - test project files + javadoc - javadoc + + </echo> + </target> + + + <target name="init"> + </target> + + <target name="build" description="Compile RSSAppender" depends="init"> + <mkdir dir="${javac.dest}"/> + <javac srcdir="src" destdir="${javac.dest}" + includes="**/*.java" + deprecation="${deprecation}" + debug="${debug}" + target="${target}" + source="${source}" + > + <classpath refid="compile.classpath"/> + </javac> + </target> + + <target name="build.tests" description="Compile tests" depends="build"> + <mkdir dir="${javac.dest}"/> + <javac srcdir="${tests.source.home}" destdir="${javac.dest}" + includes="**/*.java" + deprecation="${deprecation}" + debug="${debug}" + target="${target}" + source="${source}" + > + <classpath refid="tests.classpath"/> + </javac> + </target> + + + <!-- ================================================================= --> + <!-- Remove all generated (compiled) class files. --> + <!-- ================================================================= --> + <target name="clean" depends="init" description="Delete all compiled files."> + <delete dir="${build.dir}"/> + <delete dir="${javac.dest}"/> + </target> + + <target name="jar" depends="build"> + + <delete file="${log4j-rss.jar}" verbose="true"/> + + <jar jarfile="${log4j-rss.jar}" basedir="${javac.dest}" + includes="**/*.class" + excludes="**/Test**.class"> + <manifest> + <attribute name="Manifest-version" value="1.0"/> + <section name="org/apache/log4j/"> + <attribute name="Implementation-Title" value="log4j RSSAppender"/> + <attribute name="Implementation-Version" value="0.1"/> + <attribute name="Implementation-Vendor" value="Apache Software Foundation"/> + </section> + </manifest> + </jar> + + </target> + + <target name="run.tests" depends="build.tests"> + <junit printsummary="yes" fork="yes"> + <classpath refid="tests.classpath"/> + <formatter type="plain" usefile="false"/> + <batchtest> + <fileset dir="${tests.source.home}"> + <include name="**/*Test*.java"/> + </fileset> + </batchtest> + </junit> + </target> + + + <!-- ================================================================= --> + <!-- This target reformats the source with Jalopy. --> + <!-- ================================================================= --> + + <target name="jalopy" depends="init" description="Reformat source code using Jalopy"> + <fail unless="jalopy.files"> +Specify files to reformat with -Djalopy.files=PATTERN. +</fail> + <taskdef name="jalopy" + classname="de.hunsicker.jalopy.plugin.ant.AntPlugin"> + <classpath> + <fileset dir="${jalopy-ant.dir}/lib"> + <include name="*.jar" /> + </fileset> + </classpath> + </taskdef> + <jalopy backup="no" + convention="src/log4j-coding-convention.xml" + classpathref="compile.classpath"> + <fileset dir="${java.source.dir}" includes="${jalopy.files}"/> + </jalopy> + + </target> + + <!-- ================================================================= --> + <!-- This target builds the javadoc files. --> + <!-- ================================================================= --> + <target name="javadoc" depends="init"> + + <mkdir dir="${javadoc.dest}" /> + + <javadoc + destdir="${javadoc.dest}" + packagenames="org.apache.log4j.rss" + additionalparam="-breakiterator" + version="true" + protected="true" + author="true" + use="true" + doctitle="RSSAppender" + windowtitle="RSSAppender" + header="<b>RSSAppender</b>" + bottom="Copyright 2005 Apache Software Foundation."> + <sourcepath> + <pathelement path="src"/> + </sourcepath> + + <link href="http://java.sun.com/products/j2se/1.3/docs/api/"/> + <link href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/"/> + <classpath refid="compile.classpath"/> + </javadoc> + </target> + + +</project> + Added: logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/empty.xml URL: http://svn.apache.org/viewcvs/logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/empty.xml?rev=354238&view=auto ============================================================================== --- logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/empty.xml (added) +++ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/empty.xml Mon Dec 5 16:15:02 2005 @@ -0,0 +1,4 @@ + + + + Added: logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/garbage.xml URL: http://svn.apache.org/viewcvs/logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/garbage.xml?rev=354238&view=auto ============================================================================== --- logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/garbage.xml (added) +++ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/garbage.xml Mon Dec 5 16:15:02 2005 @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" ?> +<sdfsafsf + +adsASDAsdas + Added: logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/readme.txt URL: http://svn.apache.org/viewcvs/logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/readme.txt?rev=354238&view=auto ============================================================================== --- logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/readme.txt (added) +++ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/readme.txt Mon Dec 5 16:15:02 2005 @@ -0,0 +1,32 @@ +RSS/ATOM log4j appender 26/11 +----------------------------- + +Intro: + +src rss appender source under org.apache.log4j.rss +test unit tests. Tested with Java 1.4.2 and 1.3. on xp. Linux pending. +libs required libs including log4j,jdom,rome and junit + +Contact: + +Lara D'Abreo [EMAIL PROTECTED] [EMAIL PROTECTED] + +Example appender config: + +log4j.appender.rss=org.apache.log4j.rss.RSSAppender +log4j.appender.rss.layout=org.apache.log4j.PatternLayout +log4j.appender.rss.layout.ConversionPattern=%-5p [%t]: %m%n +# Supported Feed types (rss_0.9, rss_0.92, rss_0.93, rss_0.94, rss_2.0 or atom_0.3) +log4j.appender.rss.feedType=rss_2.0 +log4j.appender.rss.author=Rss log4j feed author +log4j.appender.rss.fileName=rssfeed.xml +log4j.appender.rss.fileAppend=true +log4j.appender.rss.link=http://www.apache.org +log4j.appender.rss.title=Rss log4j feed title +log4j.appender.rss.copyright=Rss log4j feed copyright +log4j.appender.rss.description=Rss feed created by log4j +log4j.appender.rss.msgbufferSize=10 +# Log <--> RSS Entry Map class (must implement log4j interface RSSEntryMapper) default +# log4j.appender.rss.rssEntryMapClassName=org.apache.log4j.RSSEntryMapperImpl Added: logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/rss.xml URL: http://svn.apache.org/viewcvs/logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/rss.xml?rev=354238&view=auto ============================================================================== --- logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/rss.xml (added) +++ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/rss.xml Mon Dec 5 16:15:02 2005 @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<rss xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"> + <channel> + <title>RSS Log Appender Feed</title> + <link>http://stat4j.sourceforge.net/</link> + <description>Rss feed created by stat4j RSSAppender & ROME</description> + <pubDate>Sun, 12 Jun 2005 01:19:33 GMT</pubDate> + <managingEditor>stat4j</managingEditor> + <dc:creator>stat4j</dc:creator> + <dc:date>2005-06-12T01:19:33Z</dc:date> + <item> + <title>DEBUG</title> + <description>2005-06-12 11:19:33,328 DEBUG [rss] A random log message 0</description> + <pubDate>Sun, 12 Jun 2005 01:19:33 GMT</pubDate> + <author>stat4j RSSAppender</author> + <dc:creator>stat4j RSSAppender</dc:creator> + <dc:date>2005-06-12T01:19:33Z</dc:date> + </item> + <item> + <title>DEBUG</title> + <description>2005-06-12 11:19:33,343 DEBUG [rss] A random log message 1</description> + <pubDate>Sun, 12 Jun 2005 01:19:33 GMT</pubDate> + <author>stat4j RSSAppender</author> + <dc:creator>stat4j RSSAppender</dc:creator> + <dc:date>2005-06-12T01:19:33Z</dc:date> + </item> + <item> + <title>DEBUG</title> + <description>2005-06-12 11:19:33,421 DEBUG [rss] A random log message 2</description> + <pubDate>Sun, 12 Jun 2005 01:19:33 GMT</pubDate> + <author>stat4j RSSAppender</author> + <dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">stat4j RSSAppender</dc:creator> + <dc:date xmlns:dc="http://purl.org/dc/elements/1.1/">2005-06-12T01:19:33Z</dc:date> +</item><item> + <title>DEBUG</title> + <description>2005-06-12 11:19:33,421 DEBUG [rss] A random log message 3</description> + <pubDate>Sun, 12 Jun 2005 01:19:33 GMT</pubDate> + <author>stat4j RSSAppender</author> + <dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">stat4j RSSAppender</dc:creator> + <dc:date xmlns:dc="http://purl.org/dc/elements/1.1/">2005-06-12T01:19:33Z</dc:date> +</item> + </channel> +</rss> \ No newline at end of file Added: logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/FeedWriter.java URL: http://svn.apache.org/viewcvs/logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/FeedWriter.java?rev=354238&view=auto ============================================================================== --- logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/FeedWriter.java (added) +++ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/FeedWriter.java Mon Dec 5 16:15:02 2005 @@ -0,0 +1,316 @@ +/* + * 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.rss; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.RandomAccessFile; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.jdom.output.Format; +import org.jdom.output.XMLOutputter; + +import com.sun.syndication.feed.synd.SyndContentImpl; +import com.sun.syndication.feed.synd.SyndEntry; +import com.sun.syndication.feed.synd.SyndEntryImpl; +import com.sun.syndication.feed.synd.SyndFeed; +import com.sun.syndication.feed.synd.SyndFeedImpl; +import com.sun.syndication.io.SyndFeedOutput; +import com.sun.syndication.io.WireFeedOutput; + +/** + * A <code>FeedWriter</code> handles the details of the underlying feed. + * + * @author Lara D'Abreo + */ +public class FeedWriter { + + + + /** + * hard limit for how far to scan back in feed file for enclosing xml tags + */ + public static final int SCAN_LIMIT = 1024; + + protected String feedType; + + protected SyndFeed feed; + + protected String filename; + + protected File file; + + protected boolean fileExists = false; + + protected boolean fileAppend = true; + + protected Format format; + + protected XMLOutputter outputter; + + protected WireFeedOutput wfoutput; + + protected SyndFeedOutput output; + + protected int indent; + protected String entry; + + /** + * + * @param feedType + * @param filename + * @param title + * @param description + * @param link + * @param author + * @param encoding + * @param language + * @param copyright + */ + public FeedWriter(String feedType, String filename, boolean fileAppend, + String title, String description, String link, String author, + String encoding, String language, String copyright) { + this.feedType = feedType; + this.filename = filename; + this.file = new File(filename); + this.fileAppend = fileAppend; + this.feed = new SyndFeedImpl(); + feed.setFeedType(feedType); + feed.setLink(link); + feed.setTitle(title); + feed.setDescription(description); + feed.setAuthor(author); + feed.setEncoding(encoding); + feed.setLanguage(language); + feed.setCopyright(copyright); + + // publish date set only if new file + this.format = Format.getPrettyFormat(); + if (encoding != null) { + format.setEncoding(encoding); + } + this.indent = feedType.startsWith("rss") ? 2 : 1; + this.entry = feedType.startsWith("rss") ? "item" : entry; + this.outputter = new XMLOutputter(format); + this.wfoutput = new WireFeedOutput(); + this.output = new SyndFeedOutput(); + } + + /** + * Map log4j entry to Rome entry. + * + * @param entry + * @return new Rome entry + */ + public SyndEntry toRomeEntry(RSSEntry entry) { + SyndEntry romeEntry = new SyndEntryImpl(); + + romeEntry.setAuthor(entry.getAuthor()); + + if (entry.getDescription() != null) { + SyndContentImpl content = new SyndContentImpl(); + content.setValue(entry.getDescription()); + romeEntry.setDescription(content); + + } + romeEntry.setLink(entry.getLink()); + romeEntry.setPublishedDate(entry.getPublishedDate()); + romeEntry.setTitle(entry.getTitle()); + romeEntry.setUri(entry.getUri()); + + // Categories ? + + // Modules ? + + return romeEntry; + } + + /** + * Write RSSEntries to the RSS feed. + * + * @param entries + * @throws Exception + */ + public void writeEntries(RSSEntry[] entries) throws Exception { + + // convert to rome entries + List romeEntries = new ArrayList(entries.length); + for (int i = 0; i < entries.length; ++i) { + romeEntries.add(toRomeEntry(entries[i])); + } + + feed.setEntries(romeEntries); + + // check to see if feed file exists + // if not create feed file in its entirety + if (isFeedCreateRequired()) { + feed.setPublishedDate(new Date()); + generateFeedFile(); + + // Otherwise, trim FEED closing tags and 'append' new entries + } else { + appendToFeedFile(); + } + + } + + /** + * @return true if file needs to be created + */ + protected boolean isFeedCreateRequired() { + if (!fileExists) { + fileExists = file.exists(); + } + return !fileExists || !fileAppend; + } + + /** + * Append entries to the feed file. + * + * @throws Exception + */ + protected void appendToFeedFile() throws Exception { + Writer writer = null; + try { + // trim enclosing tags + String tail = "</" + entry + ">"; + trimTailIfExists(tail); + + // rewrite last entry closing tag + writer = openWriter(true); + writer.write(tail + format.getLineSeparator()); + indent(writer,indent); + + // write entries + output.output(feed, new FilterWriter(writer, entry)); + writer.flush(); + } finally { + closeWriter(writer); + } + + } + + protected void generateFeedFile() throws Exception { + Writer writer = null; + + + + + try { + writer = openWriter(false); + output.output(feed, writer); + writer.flush(); + fileExists = true; + fileAppend = true; + } finally { + closeWriter(writer); + } + } + + + protected void indent(Writer writer, int level) throws Exception { + for (int i = 0; i < level; i++) { + writer.write(format.getIndent()); + } + } + + protected Writer openWriter(boolean append) throws Exception { + + // check parent file exists + // and create it if it doesnt + File parentDir = new File(file.getParent()); + if(!parentDir.exists()){ + parentDir.mkdirs(); + } + + return new OutputStreamWriter(new FileOutputStream(filename, append), + feed.getEncoding()); + } + + protected void closeWriter(Writer writer) { + if (writer == null) { + return; + } + try { + writer.close(); + }catch (Exception e) {} + } + + public long indexOf(RandomAccessFile file, String token) + throws IOException { + + // seek back from end + long pos = file.length() - token.length(); + int size = token.length(); + while (pos > 0 && size < SCAN_LIMIT) { + file.seek(pos); + byte[] buf = new byte[size]; + // read + file.read(buf, 0, buf.length); + // convert to String using encoding + String rawBuf = new String(buf, 0, size, feed.getEncoding()); + String sbuf = rawBuf.trim(); + if (sbuf.startsWith(token)) { + return pos; + } + + // keep going + --pos; + ++size; + + } // end while + return -1; // token not found or bof or scan limit reached + + } + + /** + * + * @param tail + * tag to find + */ + public void trimTailIfExists(String tail) throws IOException { + + RandomAccessFile raFile = null; + + try { + raFile = new RandomAccessFile(file, "rw"); + + // Look for tail in file + long pos = indexOf(raFile, tail); + + // if tail not found just return + if (pos == -1) { + return; + } + // Otherwise tail has been found, trunc it + raFile.setLength(pos); + + } finally { + try { + raFile.close(); + } catch (IOException e) { + } + } + + } + +} \ No newline at end of file Added: logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/FilterWriter.java URL: http://svn.apache.org/viewcvs/logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/FilterWriter.java?rev=354238&view=auto ============================================================================== --- logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/FilterWriter.java (added) +++ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/FilterWriter.java Mon Dec 5 16:15:02 2005 @@ -0,0 +1,105 @@ +/* +* 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.rss; + +import java.io.IOException; +import java.io.Writer; + +/** + * FilterWriter filters the stream until the entry tag is found + * and then resumes writing. + * + * + * @author Lara D'Abreo + */ +class FilterWriter extends Writer { + + protected Writer delegate; + protected String token; + protected boolean doWrite; + + public FilterWriter(Writer delegate, String token) { + this.delegate = delegate; + this.token = token; + this.doWrite = false; + } + + public void close() throws IOException { + delegate.close(); + } + + public boolean equals(Object obj) { + return delegate.equals(obj); + } + + public void flush() throws IOException { + delegate.flush(); + } + + public int hashCode() { + return delegate.hashCode(); + } + + public String toString() { + return delegate.toString(); + } + + public void write(char[] cbuf) throws IOException { + if (!doWrite) { + return; + } + delegate.write(cbuf); + } + + public void write(char[] cbuf, int off, int len) throws IOException { + if (!doWrite) { + return; + } + delegate.write(cbuf, off, len); + } + + public void write(int c) throws IOException { + if (!doWrite) { + return; + } + delegate.write(c); + } + + public void write(String str) throws IOException { + + if (!doWrite) { + doWrite = token.equals(str); + if (doWrite) { + delegate.write("<" + str); + return; + } + } + + if (!doWrite) { + return; + } + delegate.write(str); + } + + public void write(String str, int off, int len) throws IOException { + if (!doWrite) { + return; + } + delegate.write(str, off, len); + } + +} Added: logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSAppender.java URL: http://svn.apache.org/viewcvs/logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSAppender.java?rev=354238&view=auto ============================================================================== --- logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSAppender.java (added) +++ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSAppender.java Mon Dec 5 16:15:02 2005 @@ -0,0 +1,303 @@ +/* + * 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.rss; + +import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.spi.LoggingEvent; + +/** + * RSSAppender appends log events to a RSS or ATOM file. + * + * + * @author Lara D'Abreo + */ +public class RSSAppender extends AppenderSkeleton { + + /** Determines the number of messages to buffer - default is 1 */ + public static final int DEFAULT_MSG_BUFFER_SIZE = 1; + + /** + * number of log events to buffer before flushing to the feed file + */ + protected int msgbufferSize = DEFAULT_MSG_BUFFER_SIZE; + + /** + * The name of the log file. + */ + protected String fileName = null; + + /** + * Append to or truncate the file? The default value for this variable is + * <code>true</code>, meaning that by default an <code>RSSAppender</code> + * will append to an existing feed file and not truncate it. + * + * + */ + protected boolean fileAppend = true; + + /** + * Type of feed. Defaults to rss 2.0 + */ + protected String feedType = "rss_2.0"; + + /** RSS Entry Map class */ + protected String rssEntryMapClassName = RSSEntryMapperImpl.class.getName(); + + /** default feed mapper implementation */ + protected RSSEntryMapper mapper = new RSSEntryMapperImpl(); + + /** log buffer */ + protected RSSEntry[] entries; + + protected int index = 0; + + /** feed title */ + protected String title = ""; + + /** feed link */ + protected String link = ""; + + /** feed author */ + protected String author = ""; + + /** feed description */ + protected String description = ""; + + /** feed copyright */ + protected String copyright = ""; + + /** feed encoding default is UTF-8 */ + protected String encoding = "UTF-8"; + + /** feed language */ + protected String language; + + /** feed writer */ + protected FeedWriter writer; + + public RSSAppender() { + super(false); + } + + public void activateOptions() { + try { + + if (this.layout == null) { + getLogger().error("No layout set for the appender named '", + name + "'"); + } + + // Create feed writer (RSS type, details and file name) + writer = new FeedWriter(feedType, fileName, fileAppend, title, + description, link, author, encoding, language,copyright); + + // Configure mapper (class for mapping log messages to feed + // elements) + if (rssEntryMapClassName != null) { + Class c = Class.forName(rssEntryMapClassName); + mapper = (RSSEntryMapper) c.newInstance(); + } + // create log buffer + entries = new RSSEntry[msgbufferSize]; + + super.activateOptions(); + + } catch (Exception e) { + + getLogger().error( + "Exception while initializing RSSAppender named '" + name + + "'", e); + } + + } + + protected void append(LoggingEvent event) { + if (!isActive()) { + return; + } + + // Create RSS Entry + String msg = this.layout.format(event); + RSSEntry entry = mapper.toEntry(author, event, msg); + + // Add to buff + entries[index] = entry; + + + // If time to flush, write to feed file + if (index == (msgbufferSize-1)) { + try { + // flush to underlying feed + writer.writeEntries(entries); + + } catch (Exception e) { + index = 0; + this.active = false; + getLogger().info( + "Problem writing to feed for RSSAppender '" + name + + "'", e); + } + + } + index = (index + 1) % msgbufferSize; + + } + + public void close() { + } + + public boolean requiresLayout() { + return true; + } + + // Getters and setters + /** + * @return Returns the language. + */ + public String getLanguage() { + return language; + } + + /** + * @param language + * The language to set. + */ + public void setLanguage(String language) { + this.language = language; + } + + /** + * @return Returns the link. + */ + public String getLink() { + return link; + } + + /** + * @param link + * The link to set. + */ + public void setLink(String link) { + this.link = link; + } + + /** + * @return Returns the title. + */ + public String getTitle() { + return title; + } + + /** + * @param title + * The title to set. + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * @return Returns the feedType. + */ + public String getFeedType() { + return feedType; + } + + /** + * @param feedType + * The feedType to set. + */ + public void setFeedType(String feedType) { + this.feedType = feedType; + } + + /** + * @return Returns the msgbufferSize. + */ + public int getMsgbufferSize() { + return msgbufferSize; + } + + /** + * @param msgbufferSize + * The msgbufferSize to set. + */ + public void setMsgbufferSize(int msgbufferSize) { + this.msgbufferSize = msgbufferSize; + } + + /** + * @return Returns the rssEntryMapClassName. + */ + public String getRssEntryMapClassName() { + return rssEntryMapClassName; + } + + /** + * @param rssEntryMapClassName + * The rssEntryMapClassName to set. + */ + public void setRssEntryMapClassName(String rssEntryMapClassName) { + this.rssEntryMapClassName = rssEntryMapClassName; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getEncoding() { + return encoding; + } + + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + public boolean isFileAppend() { + return fileAppend; + } + + public void setFileAppend(boolean fileAppend) { + this.fileAppend = fileAppend; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + public String getCopyright() { + return copyright; + } + public void setCopyright(String copyright) { + this.copyright = copyright; + } +} Added: logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSEntry.java URL: http://svn.apache.org/viewcvs/logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSEntry.java?rev=354238&view=auto ============================================================================== --- logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSEntry.java (added) +++ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSEntry.java Mon Dec 5 16:15:02 2005 @@ -0,0 +1,136 @@ +/* + * 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.rss; + +import java.util.Date; + +/** + * A <code>RSSEntry</code> single entry in an RSS or item in an ATOM feed. + * + * @author Lara D'Abreo + * */ +public class RSSEntry { + + protected String title = ""; + + protected String description = ""; + + protected String uri = ""; + + protected String link = ""; + + protected Date publishedDate; + + protected String author =""; + + + public RSSEntry() { + publishedDate = new Date(); + + } + + /** + * @return Returns the author. + */ + public String getAuthor() { + return author; + } + + /** + * @param author + * The author to set. + */ + public void setAuthor(String author) { + this.author = author; + } + + /** + * @return Returns the description. + */ + public String getDescription() { + return description; + } + + /** + * @param description + * The description to set. + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * @return Returns the link. + */ + public String getLink() { + return link; + } + + /** + * @param link + * The link to set. + */ + public void setLink(String link) { + this.link = link; + } + + /** + * @return Returns the publishedDate. + */ + public Date getPublishedDate() { + return publishedDate; + } + + /** + * @param publishedDate + * The publishedDate to set. + */ + public void setPublishedDate(Date publishedDate) { + this.publishedDate = publishedDate; + } + + /** + * @return Returns the title. + */ + public String getTitle() { + return title; + } + + /** + * @param title + * The title to set. + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * @return Returns the uri. + */ + public String getUri() { + return uri; + } + + /** + * @param uri + * The uri to set. + */ + public void setUri(String uri) { + this.uri = uri; + } + +} \ No newline at end of file Added: logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSEntryMapper.java URL: http://svn.apache.org/viewcvs/logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSEntryMapper.java?rev=354238&view=auto ============================================================================== --- logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSEntryMapper.java (added) +++ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSEntryMapper.java Mon Dec 5 16:15:02 2005 @@ -0,0 +1,39 @@ +/* + * 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.rss; + +import org.apache.log4j.spi.LoggingEvent; + +/** + * A <code>RSSEntryMapper</code> maps LoggingEvents to + * an RSSEntry. + * + * @author Lara D'Abreo + * */ +public interface RSSEntryMapper { + + /** + * Map a log message to an RSSEntry + * + * @param feedAuthor configured author of the feed + * @param event a log message event + * @param message formatted message + * @return an RSSEntry (entry or item) element + */ + public RSSEntry toEntry(String feedAuthor,LoggingEvent event,String message); + +} Added: logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSEntryMapperImpl.java URL: http://svn.apache.org/viewcvs/logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSEntryMapperImpl.java?rev=354238&view=auto ============================================================================== --- logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSEntryMapperImpl.java (added) +++ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/src/org/apache/log4j/rss/RSSEntryMapperImpl.java Mon Dec 5 16:15:02 2005 @@ -0,0 +1,49 @@ +/* + * 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.rss; + +import java.util.Date; + +import org.apache.log4j.spi.LoggingEvent; + +/** + * Default RSSEntry mapping from a Log message to an RSS Entry. + * + * @author Lara D'Abreo + * + */ +public class RSSEntryMapperImpl implements RSSEntryMapper { + + /** + * + */ + public RSSEntryMapperImpl() { + super(); + } + + + public RSSEntry toEntry(String feedAuthor,LoggingEvent event,String message) { + RSSEntry entry = new RSSEntry(); + + entry.setAuthor(event.getLoggerName()); + entry.setTitle(event.getLevel().toString()); + entry.setDescription(message); + entry.setPublishedDate(new Date(System.currentTimeMillis())); + return entry; + } + +} Added: logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/test/TestRSSAppender.java URL: http://svn.apache.org/viewcvs/logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/test/TestRSSAppender.java?rev=354238&view=auto ============================================================================== --- logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/test/TestRSSAppender.java (added) +++ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/test/TestRSSAppender.java Mon Dec 5 16:15:02 2005 @@ -0,0 +1,93 @@ +/* + * 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. + */ + +import java.net.URL; + +import junit.framework.TestCase; + +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; + +/** + * @author Lara D'Abreo + * + */ +public class TestRSSAppender extends TestCase { + + Logger logger = null; + + public TestRSSAppender() { + + } + + public void setUp() { + + URL url = TestRSSAppender.class.getResource("log.properties"); + PropertyConfigurator.configure(url); + logger = Logger.getLogger("rss"); + } + + public TestRSSAppender(String arg0) { + super(arg0); + } + + public void testBasic() { + int limit = (int) (Math.random() * 10); + generateLogs(limit); + } + + public void generateLogs(int limit) { + + for (int i = 0; i < limit; ++i) { + String log = "A random log message " + i; + logger.info("info" + log); + logger.debug("debug " + log); + logger.error("error " + log, new Exception()); + logger.error("error " + log); + logger.warn(log); + logger.fatal("fatal " + log); + logger.trace("trace " + log); + + } + } + + public void testThreadedRSSAppender() { + int threads = (int) (Math.random() * 100); + for (int i = 0; i < threads; ++i) { + final int j = i; + Runnable r = new Runnable() { + public void run() { + logger.info("spawning thread " + j); + testBasic(); + } + }; + + Thread t = new Thread(r); + t.start(); + sleep((int) (Math.random() * 20)); + } + // wait a bit + sleep(1000); + + } + + public static void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (Exception e) { + } + } +} \ No newline at end of file Added: logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/test/TestTailSeek.java URL: http://svn.apache.org/viewcvs/logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/test/TestTailSeek.java?rev=354238&view=auto ============================================================================== --- logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/test/TestTailSeek.java (added) +++ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/test/TestTailSeek.java Mon Dec 5 16:15:02 2005 @@ -0,0 +1,91 @@ + +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.io.RandomAccessFile; + +import junit.framework.TestCase; + +import org.apache.log4j.rss.FeedWriter; + +/* + * 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. + */ + +/** + * @author Lara D'Abreo + * + */ +public class TestTailSeek extends TestCase { + + public static final String RSS_TAIL = "</rss>"; + public static final String EMPTY_FILE = "empty.xml"; + public static final String RSS_FILE = "rss.xml"; + public static final String ATOM_FILE = "atom.xml"; + public static final String GARBAGE_FILE = "garbage.xml"; + + /** + * + */ + public TestTailSeek() { + super(); + } + + /** + * @param arg0 + */ + public TestTailSeek(String arg0) { + super(arg0); + // TODO Auto-generated constructor stub + } + + public void testSeekNoTail() throws Exception { + FeedWriter writer = new FeedWriter("rss_2.0", GARBAGE_FILE, true, + "", "", "", "","UTF-8","",""); + RandomAccessFile file = new RandomAccessFile(GARBAGE_FILE, "r"); + long pos = writer.indexOf(file, RSS_TAIL); + assertEquals(pos, -1); + file.close(); + + } + + public void testSeekEmptyFile() throws Exception { + FeedWriter writer = new FeedWriter("rss_2.0", EMPTY_FILE, true, + "", "", "", "","UTF-8","",""); + RandomAccessFile file = new RandomAccessFile(EMPTY_FILE, "r"); + long pos = writer.indexOf(file, RSS_TAIL); + assertEquals(pos, -1); + file.close(); + } + + public void testSeekSingleTail() throws Exception { + FeedWriter writer = new FeedWriter("rss_2.0", RSS_FILE, true, + "", "", "", "","UTF-8","",""); + RandomAccessFile file = new RandomAccessFile(RSS_FILE, "r"); + writer.trimTailIfExists(RSS_TAIL); + long pos = writer.indexOf(file, RSS_TAIL); + assertEquals(pos, -1); + // append tail + FileOutputStream fos = new FileOutputStream(RSS_FILE, true); + OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8"); + osw.write(RSS_TAIL); + osw.flush(); + osw.close(); + // check tail is back again + pos = writer.indexOf(file, RSS_TAIL); + assertTrue(pos != -1); + } + + +} \ No newline at end of file Added: logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/test/log.properties URL: http://svn.apache.org/viewcvs/logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/test/log.properties?rev=354238&view=auto ============================================================================== --- logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/test/log.properties (added) +++ logging/sandbox/log4j/contribs/trunk/LaraDAbreo/RSSAppender/test/log.properties Mon Dec 5 16:15:02 2005 @@ -0,0 +1,38 @@ + +# Development Root Debug Level +# ====================== +log4j.rootLogger=DEBUG,console +log4j.logger.rss=DEBUG,rss + +# Configure the RSS appender +# ========================= +log4j.appender.rss=org.apache.log4j.rss.RSSAppender +log4j.appender.rss.layout=org.apache.log4j.PatternLayout +log4j.appender.rss.layout.ConversionPattern=%-5p [%t]: %m%n +# Supported Feed types (rss_0.9, rss_0.92, rss_0.93, rss_0.94, rss_2.0 or atom_0.3) +log4j.appender.rss.feedType=rss_2.0 +log4j.appender.rss.author=Rss log4j feed author +log4j.appender.rss.fileName=rssfeed.xml +log4j.appender.rss.fileAppend=false +log4j.appender.rss.link=http://www.apache.org +log4j.appender.rss.title=Rss log4j feed title +log4j.appender.rss.copyright=Rss log4j feed copyright +log4j.appender.rss.description=Rss feed created by log4j +log4j.appender.rss.msgbufferSize=10 +# Log <--> RSS Entry Map class (must implement log4j interface RSSEntryMapper) default +# log4j.appender.rss.rssEntryMapClassName=org.apache.log4j.RSSEntryMapperImpl + + + +# Configure the Console (System.err) +# ========================= +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.Target=System.err +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=%-5p [%t]: %m%n + + + + + + --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]