I wrote: > Please, do NOT include it into cocoon_20_branch CVS on apache.org, it's > working, but eat huge quantity of memory, and displayed data are raw. > This is not for final administrators yet.
Ok, this time, I have a better quality patch for both branchs. The status page display every key in each store correponding to a not-null object and the class of this object. Still to be done : - Use better names instead of keys. - Add a counter of cache-hit for each object. -- Sébastien Koechlin - IVision - [EMAIL PROTECTED]
diff -u -r -x CVS xml-cocoon2.cocoon_20_branch/src/org/apache/cocoon/components/store/StoreJanitor.java xml-cocoon2/src/org/apache/cocoon/components/store/StoreJanitor.java --- xml-cocoon2.cocoon_20_branch/src/org/apache/cocoon/components/store/StoreJanitor.java Thu Dec 6 12:32:45 2001 +++ xml-cocoon2/src/org/apache/cocoon/components/store/StoreJanitor.java Wed +Dec 5 18:40:12 2001 @@ -23,4 +23,7 @@ /** unregister method for the stores */ void unregister(Store store); + + /** get an iterator to list registered stores */ + java.util.Iterator iterator(); } diff -u -r -x CVS xml-cocoon2.cocoon_20_branch/src/org/apache/cocoon/components/store/StoreJanitorImpl.java xml-cocoon2/src/org/apache/cocoon/components/store/StoreJanitorImpl.java --- xml-cocoon2.cocoon_20_branch/src/org/apache/cocoon/components/store/StoreJanitorImpl.java Thu Dec 6 12:32:46 2001 +++ xml-cocoon2/src/org/apache/cocoon/components/store/StoreJanitorImpl.java Thu +Dec 6 17:17:50 2001 @@ -16,6 +16,7 @@ import org.apache.avalon.framework.thread.ThreadSafe; import java.util.ArrayList; +import java.util.Iterator; /** * This class is a implentation of a StoreJanitor. Store classes @@ -170,6 +171,22 @@ } } + /** + * This method return a java.util.Iterator of every registered stores + * + * <i>The iterators returned is fail-fast: if list is structurally + * modified at any time after the iterator is created, in any way, the + * iterator will throw a ConcurrentModificationException. Thus, in the + * face of concurrent modification, the iterator fails quickly and + * cleanly, rather than risking arbitrary, non-deterministic behavior at + * an undetermined time in the future.</i> + * + * @return a java.util.Iterator + */ + public Iterator iterator() { + return this.getStoreList().iterator(); + } + /** * Round Robin alghorithm for freeing the registerd caches. */ diff -u -r -x CVS xml-cocoon2.cocoon_20_branch/src/org/apache/cocoon/generation/StatusGenerator.java xml-cocoon2/src/org/apache/cocoon/generation/StatusGenerator.java --- xml-cocoon2.cocoon_20_branch/src/org/apache/cocoon/generation/StatusGenerator.java Thu Dec 6 12:32:46 2001 +++ xml-cocoon2/src/org/apache/cocoon/generation/StatusGenerator.java Thu Dec 6 +18:39:34 2001 @@ -7,7 +7,15 @@ *****************************************************************************/ package org.apache.cocoon.generation; +import org.apache.avalon.framework.component.ComponentException; +import org.apache.avalon.framework.component.ComponentManager; +import org.apache.avalon.framework.component.Composable; + import org.apache.avalon.excalibur.pool.Recyclable; + +import org.apache.cocoon.components.store.StoreJanitor; +import org.apache.cocoon.components.store.Store; + import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; @@ -16,10 +24,8 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.text.DateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.StringTokenizer; +import java.util.*; + /** Generates an XML representation of the current status of Cocoon. * Potted DTD: @@ -47,10 +53,15 @@ * * @author <a href="mailto:[EMAIL PROTECTED]">Paul Russell</a> (Luminas Limited) * @author <a href="mailto:[EMAIL PROTECTED]">Stefano Mazzocchi</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Sébastien Kœchlin</a> +(iVision) * @version CVS $Revision: 1.4.2.3 $ $Date: 2001/10/11 08:56:12 $ */ public class StatusGenerator extends ComposerGenerator implements Recyclable { + /** The StoreJanitor used to get cache statistics + */ + protected StoreJanitor storejanitor; + /** The XML namespace for the output document. */ protected static final String namespace = @@ -61,6 +72,20 @@ protected static final String xlinkNamespace = "http://www.w3.org/1999/xlink"; + /** + * Set the current <code>ComponentManager</code> instance used by this + * <code>Composable</code>. + * Need to get statistics about cache hits + */ + public void compose(ComponentManager manager) throws ComponentException { + super.compose(manager); + try { + this.storejanitor = (StoreJanitor)manager.lookup(StoreJanitor.ROLE); + } catch(ComponentException ce) { + getLogger().info("StoreJanitor is not available. Sorry, no cache +statistics"); + } + } + /** Generate the status information in XML format. * @throws SAXException * when there is a problem creating the output SAX events. @@ -149,6 +174,57 @@ paths.add(tokenizer.nextToken()); } addMultilineValue(ch, "classpath", paths); + // END ClassPath + + // BEGIN Cache + startGroup(ch, "Store-Janitor"); + + // For each element in StoreJanitor + Iterator i = this.storejanitor.iterator(); + while( i.hasNext() ) { + Store store = (Store) i.next(); + startGroup(ch, store.getClass().getName()+" (hash = +0x"+Integer.toHexString(store.hashCode())+")" ); + int size = 0; + int empty = 0; + atts.addAttribute(namespace, "name", "name", "CDATA", "cached"); + ch.startElement(namespace, "value", "value", atts); + // For each element in Store + Enumeration e = store.keys(); + atts.clear(); + while( e.hasMoreElements() ) { + size++; + Object key = e.nextElement(); + Object val = store.get( key ); + String line = null; + if( val == null ) { + empty++; + } else { + line = key.toString() + " (class: " + + val.getClass().getName() + + ")" ; + ch.startElement(namespace, "line", "line", atts); + ch.characters(line.toCharArray(), 0, line.length()); + ch.endElement(namespace, "line", "line"); + }; + + + }; + + if (size == 0) { + atts.clear(); + ch.startElement(namespace, "line", "line", atts); + String value = "[empty]"; + ch.characters(value.toCharArray(), 0, value.length()); + ch.endElement(namespace, "line", "line"); + } + + ch.endElement(namespace, "value", "value"); + + addValue(ch, "size", String.valueOf(size) + " items in cache (" + empty + +" are empty)"); + endGroup(ch); + }; + endGroup(ch); + // END Cache // BEGIN OS info endGroup(ch); diff -u -r -x CVS xml-cocoon2.cocoon_20_branch/webapp/stylesheets/system/status2html.xsl xml-cocoon2/webapp/stylesheets/system/status2html.xsl --- xml-cocoon2.cocoon_20_branch/webapp/stylesheets/system/status2html.xsl Thu Dec 6 12:32:51 2001 +++ xml-cocoon2/webapp/stylesheets/system/status2html.xsl Thu Dec 6 11:15:53 +2001 @@ -71,21 +71,45 @@ </xsl:template> - <xsl:template match="status:value"> - <tr> - <td bgcolor="#0086b2" valign="top" align="left"> - <FONT face="arial,helvetica,sanserif" color="#ffffff"> - <xsl:value-of select="@status:name"/> - </FONT> - </td> - <td bgcolor="ffffff" width="100%"> - <FONT face="arial,helvetica,sanserif"> - <xsl:value-of select="." /> - </FONT> - </td> - </tr> + <xsl:template match="status:value[count(status:line) <= 1]"> + <tr> + <td bgcolor="#0086b2" valign="top" align="left"> + <font face="arial,helvetica,sanserif" color="#ffffff"> + <xsl:value-of select="@status:name"/> + </font> + </td> + <td bgcolor="ffffff" width="100%"> + <font face="arial,helvetica,sanserif"> + <xsl:value-of select="status:line" /> + </font> + </td> + </tr> + </xsl:template> - </xsl:template> + + <xsl:template match="status:value[count(status:line) > 1]"> + <tr> + <td bgcolor="#0086b2" valign="top" align="left"> + <font face="arial,helvetica,sanserif" color="#ffffff"> + <xsl:value-of select="@status:name"/> + </font> + </td> + <td bgcolor="ffffff" width="100%"> + <ul> + <xsl:apply-templates /> + </ul> + </td> + </tr> + </xsl:template> + + + <xsl:template match="status:line"> + <li> + <font face="arial,helvetica,sanserif"> + <xsl:value-of select="." /> + </font> + </li> + </xsl:template> <xsl:template match="status:value[../@status:name='memory' and ( @status:name='total' or @status:name='free')]">
--- xml-cocoon2.head/src/org/apache/cocoon/generation/StatusGenerator.java Thu Dec 6 14:13:47 2001 +++ xml-cocoon2/src/org/apache/cocoon/generation/StatusGenerator.java Thu Dec 6 +18:54:12 2001 @@ -52,6 +53,7 @@ * * @author <a href="mailto:[EMAIL PROTECTED]">Paul Russell</a> (Luminas Limited) * @author <a href="mailto:[EMAIL PROTECTED]">Stefano Mazzocchi</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Sébastien Kœchlin</a> +(iVision) * @version CVS $Revision: 1.8 $ $Date: 2001/12/06 13:13:47 $ */ public class StatusGenerator extends ComposerGenerator implements Recyclable { @@ -181,28 +183,30 @@ Iterator i = this.storejanitor.iterator(); while( i.hasNext() ) { Store store = (Store) i.next(); - startGroup(ch, store.getClass().getName()+" (hash = "+store.hashCode()+")" ); + startGroup(ch, store.getClass().getName()+" (hash = +0x"+Integer.toHexString(store.hashCode())+")" ); int size = 0; + int empty = 0; atts.addAttribute(namespace, "name", "name", "CDATA", "cached"); ch.startElement(namespace, "value", "value", atts); // For each element in Store Enumeration e = store.keys(); - List cachelist = new ArrayList(); + atts.clear(); while( e.hasMoreElements() ) { size++; - atts.clear(); - - ch.startElement(namespace, "line", "line", atts); - - Object o = e.nextElement(); - String value = - o.toString() + " (hash: " + - o.hashCode() + " | class: " + - o.getClass().getName() + + Object key = e.nextElement(); + Object val = store.get( key ); + String line = null; + if( val == null ) { + empty++; + } else { + line = key.toString() + " (class: " + + val.getClass().getName() + ")" ; - - ch.characters(value.toCharArray(), 0, value.length()); + ch.startElement(namespace, "line", "line", atts); + ch.characters(line.toCharArray(), 0, line.length()); ch.endElement(namespace, "line", "line"); + }; + }; @@ -216,7 +220,7 @@ ch.endElement(namespace, "value", "value"); - addValue(ch, "size", String.valueOf(size) + " items in cache"); + addValue(ch, "size", String.valueOf(size) + " items in cache (" + empty + +" are empty)"); endGroup(ch); }; endGroup(ch);
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, email: [EMAIL PROTECTED]