
erik at ehatchersolutions
Apr 27, 2007, 2:39 AM
Post #1 of 3
(1448 views)
Permalink
|
|
Fwd: svn commit: r532975 - in /lucene/solr/trunk: example/solr/conf/ src/java/org/apache/solr/handler/ src/java/org/apache/solr/handler/admin/ src/test/org/apache/solr/handler/admin/
|
|
ok folks, time to bake this kind of stuff into solr-ruby for one, and also UI-wise into flare! who's with me?! :) Erik Begin forwarded message: > From: ryan[at]apache.org > Date: April 27, 2007 1:56:08 AM EDT > To: solr-commits[at]lucene.apache.org > Subject: svn commit: r532975 - in /lucene/solr/trunk: example/solr/ > conf/ src/java/org/apache/solr/handler/ src/java/org/apache/solr/ > handler/admin/ src/test/org/apache/solr/handler/admin/ > Reply-To: solr-dev[at]lucene.apache.org > > Author: ryan > Date: Thu Apr 26 22:56:07 2007 > New Revision: 532975 > > URL: http://svn.apache.org/viewvc?view=rev&rev=532975 > Log: > Adding 'Luke' request handler and other admin helpers: SOLR-163 > > Added: > lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > LukeRequestHandler.java (with props) > lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > PluginInfoHandler.java (with props) > lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > PropertiesRequestHandler.java (with props) > lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > SystemInfoHandler.java (with props) > lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > ThreadDumpHandler.java (with props) > lucene/solr/trunk/src/test/org/apache/solr/handler/admin/ > lucene/solr/trunk/src/test/org/apache/solr/handler/admin/ > SystemInfoHandlerTest.java (with props) > Modified: > lucene/solr/trunk/example/solr/conf/solrconfig.xml > lucene/solr/trunk/src/java/org/apache/solr/handler/ > IndexInfoRequestHandler.java > > Modified: lucene/solr/trunk/example/solr/conf/solrconfig.xml > URL: http://svn.apache.org/viewvc/lucene/solr/trunk/example/solr/ > conf/solrconfig.xml?view=diff&rev=532975&r1=532974&r2=532975 > ====================================================================== > ======== > --- lucene/solr/trunk/example/solr/conf/solrconfig.xml (original) > +++ lucene/solr/trunk/example/solr/conf/solrconfig.xml Thu Apr 26 > 22:56:07 2007 > @@ -399,6 +399,13 @@ > <requestHandler name="/update/csv" > class="solr.CSVRequestHandler" startup="lazy"> > </requestHandler> > > + <!-- Admin Handlers. TODO? There could be a single handler that > loads them all... --> > + <requestHandler name="/admin/luke" > class="org.apache.solr.handler.admin.LukeRequestHandler" /> > + <requestHandler name="/admin/system" > class="org.apache.solr.handler.admin.SystemInfoHandler" /> > + <requestHandler name="/admin/plugins" > class="org.apache.solr.handler.admin.PluginInfoHandler" /> > + <requestHandler name="/admin/threads" > class="org.apache.solr.handler.admin.ThreadDumpHandler" /> > + <requestHandler name="/admin/properties" > class="org.apache.solr.handler.admin.PropertiesRequestHandler" /> > + > > <!-- queryResponseWriter plugins... query responses will be > written using the > writer specified by the 'wt' request parameter matching the > name of a registered > > Modified: lucene/solr/trunk/src/java/org/apache/solr/handler/ > IndexInfoRequestHandler.java > URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/ > apache/solr/handler/IndexInfoRequestHandler.java? > view=diff&rev=532975&r1=532974&r2=532975 > ====================================================================== > ======== > --- lucene/solr/trunk/src/java/org/apache/solr/handler/ > IndexInfoRequestHandler.java (original) > +++ lucene/solr/trunk/src/java/org/apache/solr/handler/ > IndexInfoRequestHandler.java Thu Apr 26 22:56:07 2007 > @@ -32,6 +32,11 @@ > import java.util.Map; > import java.util.HashMap; > > +/** > + * TODO? delete me? This is now a subset of LukeRequestHandler. > + * Since it was not released in 1.1 should it be deleted before 1.2? > + */ > +@Deprecated > public class IndexInfoRequestHandler extends RequestHandlerBase { > > public void handleRequestBody(SolrQueryRequest req, > SolrQueryResponse rsp) { > @@ -98,4 +103,5 @@ > return "$URL: https://svn.apache.org/repos/asf/lucene/solr/ > trunk/src/java/org/apache/solr/request/IndexInfoRequestHandler.java > $"; > } > } > + > > > Added: lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > LukeRequestHandler.java > URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/ > apache/solr/handler/admin/LukeRequestHandler.java?view=auto&rev=532975 > ====================================================================== > ======== > --- lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > LukeRequestHandler.java (added) > +++ lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > LukeRequestHandler.java Thu Apr 26 22:56:07 2007 > @@ -0,0 +1,479 @@ > +/** > + * Licensed to the Apache Software Foundation (ASF) under one or more > + * contributor license agreements. See the NOTICE file > distributed with > + * this work for additional information regarding copyright > ownership. > + * The ASF licenses this file to You under the Apache License, > Version 2.0 > + * (the "License"); you may not use this file except in compliance > with > + * the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > + * See the License for the specific language governing permissions > and > + * limitations under the License. > + */ > + > +package org.apache.solr.handler.admin; > + > +import java.io.IOException; > +import java.net.MalformedURLException; > +import java.net.URL; > +import java.util.Collection; > +import java.util.Date; > +import java.util.HashMap; > +import java.util.HashSet; > +import java.util.LinkedList; > +import java.util.List; > +import java.util.Map; > +import java.util.Set; > +import java.util.logging.Level; > +import java.util.logging.Logger; > + > +import org.apache.lucene.document.Document; > +import org.apache.lucene.document.Fieldable; > +import org.apache.lucene.index.IndexReader; > +import org.apache.lucene.index.Term; > +import org.apache.lucene.index.TermEnum; > +import org.apache.lucene.index.TermFreqVector; > +import org.apache.lucene.search.MatchAllDocsQuery; > +import org.apache.lucene.search.Query; > +import org.apache.lucene.store.Directory; > +import org.apache.lucene.util.PriorityQueue; > +import org.apache.solr.core.SolrConfig; > +import org.apache.solr.core.SolrException; > +import org.apache.solr.handler.RequestHandlerBase; > +import org.apache.solr.handler.RequestHandlerUtils; > +import org.apache.solr.request.SolrParams; > +import org.apache.solr.request.SolrQueryRequest; > +import org.apache.solr.request.SolrQueryResponse; > +import org.apache.solr.schema.FieldType; > +import org.apache.solr.schema.IndexSchema; > +import org.apache.solr.schema.SchemaField; > +import org.apache.solr.search.SolrIndexSearcher; > +import org.apache.solr.search.SolrQueryParser; > +import org.apache.solr.util.NamedList; > +import org.apache.solr.util.SimpleOrderedMap; > + > +/** > + * This handler exposes the internal lucene index. It is inspired > by and > + * modeled on Luke, the Lucene Index Browser by Andrzej Bialecki. > + * http://www.getopt.org/luke/ > + * <p> > + * NOTE: the response format is still likely to change. It should > be designed so > + * that it works nicely with an XSLT transformation. Untill we > have a nice > + * XSLT frontend for /admin, the format is still open to change. > + * </p> > + * > + * For more documentation see: > + * > + * > + * @author ryan > + * @version $Id$ > + * @since solr 1.2 > + */ > +public class LukeRequestHandler extends RequestHandlerBase > +{ > + private static Logger log = Logger.getLogger > (LukeRequestHandler.class.getName()); > + > + public static final String NUMTERMS = "numTerms"; > + public static final String DOC_ID = "docID"; > + public static final String ID = "id"; > + public static final int DEFAULT_COUNT = 10; > + > + @Override > + public void handleRequestBody(SolrQueryRequest req, > SolrQueryResponse rsp) throws Exception > + { > + RequestHandlerUtils.addExperimentalFormatWarning( rsp ); > + > + IndexSchema schema = req.getSchema(); > + SolrIndexSearcher searcher = req.getSearcher(); > + IndexReader reader = searcher.getReader(); > + SolrParams params = req.getParams(); > + > + // Always show the core lucene info > + rsp.add("index", getIndexInfo(reader) ); > + > + Integer docID = params.getInt( DOC_ID ); > + if( docID == null && params.get( ID ) != null ) { > + // Look for somethign with a given solr ID > + SchemaField uniqueKey = schema.getUniqueKeyField(); > + String v = uniqueKey.getType().toInternal( params.get(ID) ); > + Term t = new Term( uniqueKey.getName(), v ); > + docID = searcher.getFirstMatch( t ); > + if( docID < 0 ) { > + throw new SolrException( 404, "Can't find document: > "+params.get( ID ) ); > + } > + } > + > + // Read the document from the index > + if( docID != null ) { > + Document doc = null; > + try { > + doc = reader.document( docID ); > + } > + catch( Exception ex ) {} > + if( doc == null ) { > + throw new SolrException( 404, "Can't find document: > "+docID ); > + } > + > + SimpleOrderedMap<Object> info = getDocumentFieldsInfo( doc, > docID, reader, schema ); > + > + SimpleOrderedMap<Object> docinfo = new > SimpleOrderedMap<Object>(); > + docinfo.add( "docID", docID ); > + docinfo.add( "lucene", info ); > + docinfo.add( "solr", doc ); > + rsp.add( "doc", docinfo ); > + } > + else { > + // If no doc is given, show all fields and top terms > + int numTerms = params.getInt( NUMTERMS, DEFAULT_COUNT ); > + Set<String> fields = null; > + if( params.get( SolrParams.FL ) != null ) { > + fields = new HashSet<String>(); > + for( String f : params.getParams( SolrParams.FL ) ) { > + fields.add( f ); > + } > + } > + rsp.add( "key", getFieldFlagsKey() ); > + rsp.add( "fields", getIndexedFieldsInfo( searcher, fields, > numTerms ) ) ; > + } > + } > + > + /** > + * @return a string representing a Fieldable's flags. > + */ > + private static String getFieldFlags( Fieldable f ) > + { > + StringBuilder flags = new StringBuilder(); > + flags.append( (f != null && f.isIndexed > ()) ? 'I' : '-' ); > + flags.append( (f != null && f.isTokenized > ()) ? 'T' : '-' ); > + flags.append( (f != null && f.isStored > ()) ? 'S' : '-' ); > + flags.append > ( (false) ? 'M' : > '-' ); // SchemaField Specific > + flags.append( (f != null && f.isTermVectorStored > ()) ? 'V' : '-' ); > + flags.append( (f != null && f.isStoreOffsetWithTermVector > ()) ? 'o' : '-' ); > + flags.append( (f != null && f.isStorePositionWithTermVector > ()) ? 'p' : '-' ); > + flags.append( (f != null && f.getOmitNorms > ()) ? 'O' : '-' ); > + flags.append( (f != null && f.isLazy > ()) ? 'L' : '-' ); > + flags.append( (f != null && f.isBinary > ()) ? 'B' : '-' ); > + flags.append( (f != null && f.isCompressed > ()) ? 'C' : '-' ); > + flags.append > ( (false) ? 'f' : > '-' ); // SchemaField Specific > + flags.append > ( (false) ? 'l' : > '-' ); // SchemaField Specific > + return flags.toString(); > + } > + > + /** > + * @return a string representing a SchemaField's flags. > + */ > + private static String getFieldFlags( SchemaField f ) > + { > + FieldType t = (f==null) ? null : f.getType(); > + > + // see: http://www.nabble.com/schema-field-properties- > tf3437753.html#a9585549 > + boolean lazy = false; // "lazy" is purely a property of > reading fields > + boolean binary = false; // Currently not possible > + > + StringBuilder flags = new StringBuilder(); > + flags.append( (f != null && f.indexed()) ? 'I' : > '-' ); > + flags.append( (t != null && t.isTokenized()) ? 'T' : > '-' ); > + flags.append( (f != null && f.stored()) ? 'S' : > '-' ); > + flags.append( (f != null && f.multiValued()) ? 'M' : > '-' ); > + flags.append( (f != null && f.storeTermVector() ) ? 'V' : > '-' ); > + flags.append( (f != null && f.storeTermOffsets() ) ? 'o' : > '-' ); > + flags.append( (f != null && f.storeTermPositions() ) ? 'p' : > '-' ); > + flags.append( (f != null && f.omitNorms()) ? 'O' : > '-' ); > + flags.append( (lazy) ? 'L' : > '-' ); > + flags.append( (binary) ? 'B' : > '-' ); > + flags.append( (f != null && f.isCompressed()) ? 'C' : > '-' ); > + flags.append( (f != null && f.sortMissingFirst() ) ? 'f' : > '-' ); > + flags.append( (f != null && f.sortMissingLast() ) ? 'l' : > '-' ); > + return flags.toString(); > + } > + > + /** > + * @return a key to what each character means > + */ > + private static SimpleOrderedMap<String> getFieldFlagsKey() > + { > + SimpleOrderedMap<String> key = new SimpleOrderedMap<String>(); > + key.add( "I", "Indexed" ); > + key.add( "T", "Tokenized" ); > + key.add( "S", "Stored" ); > + key.add( "M", "Multivalued" ); > + key.add( "V", "TermVector Stored" ); > + key.add( "o", "Store Offset With TermVector" ); > + key.add( "p", "Store Position With TermVector" ); > + key.add( "O", "Omit Norms" ); > + key.add( "L", "Lazy" ); > + key.add( "B", "Binary" ); > + key.add( "C", "Compressed" ); > + key.add( "f", "Sort Missing First" ); > + key.add( "l", "Sort Missing Last" ); > + return key; > + } > + > + private static SimpleOrderedMap<Object> getDocumentFieldsInfo > ( Document doc, int docID, IndexReader reader, IndexSchema schema ) > throws IOException > + { > + SimpleOrderedMap<Object> finfo = new SimpleOrderedMap<Object>(); > + for( Object o : doc.getFields() ) { > + Fieldable fieldable = (Fieldable)o; > + SimpleOrderedMap<Object> f = new SimpleOrderedMap<Object>(); > + > + SchemaField sfield = schema.getFieldOrNull( fieldable.name() ); > + FieldType ftype = (sfield==null)?null:sfield.getType(); > + > + f.add( "type", (ftype==null)?null:ftype.getTypeName() ); > + f.add( "schema", getFieldFlags( sfield ) ); > + f.add( "flags", getFieldFlags( fieldable ) ); > + > + Term t = new Term( fieldable.name(), fieldable.stringValue() ); > + f.add( "value", (ftype==null)?null:ftype.toExternal > ( fieldable ) ); > + f.add( "internal", fieldable.stringValue() ); // may be a > binary number > + f.add( "boost", fieldable.getBoost() ); > + > + // TODO? how can this ever be 0?! it is in the document! > + int freq = reader.docFreq( t ); > + if( freq > 0 ) { > + f.add( "docFreq", reader.docFreq( t ) ); > + } > + else { > + f.add( "docFreq", "zero! How can that be?" ); > + } > + > + // If we have a term vector, return that > + if( fieldable.isTermVectorStored() ) { > + try { > + TermFreqVector v = reader.getTermFreqVector( docID, > fieldable.name() ); > + if( v != null ) { > + SimpleOrderedMap<Integer> tfv = new > SimpleOrderedMap<Integer>(); > + for( int i=0; i<v.size(); i++ ) { > + tfv.add( v.getTerms()[i], v.getTermFrequencies()[i] ); > + } > + f.add( "termVector", tfv ); > + } > + } > + catch( Exception ex ) { > + log.log( Level.WARNING, "error writing term vector", ex ); > + } > + } > + > + finfo.add( fieldable.name(), f ); > + } > + return finfo; > + } > + > + @SuppressWarnings("unchecked") > + private static SimpleOrderedMap<Object> getIndexedFieldsInfo( > + final SolrIndexSearcher searcher, final Set<String> fields, > final int numTerms ) > + throws Exception > + { > + Query matchAllDocs = new MatchAllDocsQuery(); > + SolrQueryParser qp = searcher.getSchema().getSolrQueryParser > (null); > + > + int filterCacheSize = SolrConfig.config.getInt( "query/ > filterCache/@size", -1 ); > + IndexReader reader = searcher.getReader(); > + IndexSchema schema = searcher.getSchema(); > + > + // Walk the term enum and keep a priority quey for each map in > our set > + Map<String,TopTermQueue> ttinfo = getTopTerms(reader, fields, > numTerms, null ); > + SimpleOrderedMap<Object> finfo = new SimpleOrderedMap<Object>(); > + Collection<String> fieldNames = reader.getFieldNames > (IndexReader.FieldOption.ALL); > + for (String fieldName : fieldNames) { > + if( fields != null && !fields.contains( fieldName ) ) { > + continue; // if a field is specified, only return one > + } > + > + SimpleOrderedMap<Object> f = new SimpleOrderedMap<Object>(); > + > + SchemaField sfield = schema.getFieldOrNull( fieldName ); > + FieldType ftype = (sfield==null)?null:sfield.getType(); > + > + f.add( "type", (ftype==null)?null:ftype.getTypeName() ); > + f.add( "schema", getFieldFlags( sfield ) ); > + > + Query q = qp.parse( fieldName+":[* TO *]" ); > + int docCount = searcher.numDocs( q, matchAllDocs ); > +// TODO? Is there a way to get the Fieldable infomation for this > field? > +// The following approach works fine for stored fields, but does > not work for non-stored fields > +// if( docCount > 0 ) { > +// // Find a document with this field > +// DocList ds = searcher.getDocList( q, (Query)null, (Sort) > null, 0, 1 ); > +// try { > +// Document doc = searcher.doc( ds.iterator().next() ); > +// Fieldable fld = doc.getFieldable( fieldName ); > +// f.add( "index", getFieldFlags( fld ) ); > +// } > +// catch( Exception ex ) { > +// log.warning( "error reading field: "+fieldName ); > +// } > +// // Find one document so we can get the fieldable > +// } > + f.add( "docs", docCount ); > + > + TopTermQueue topTerms = ttinfo.get( fieldName ); > + if( topTerms != null ) { > + f.add( "distinct", topTerms.distinctTerms ); > + > + // TODO? is this the correct logic? > + f.add( "cacheableFaceting", topTerms.distinctTerms < > filterCacheSize ); > + > + // Only show them if we specify something > + f.add( "topTerms", topTerms.toNamedList( searcher.getSchema > () ) ); > + } > + > + // Add the field > + finfo.add( fieldName, f ); > + } > + return finfo; > + } > + > + > + private static SimpleOrderedMap<Object> getIndexInfo > ( IndexReader reader ) throws IOException > + { > + // Count the terms > + TermEnum te = reader.terms(); > + int numTerms = 0; > + while (te.next()) { > + numTerms++; > + } > + > + Directory dir = reader.directory(); > + SimpleOrderedMap<Object> indexInfo = new > SimpleOrderedMap<Object>(); > + indexInfo.add("numDocs", reader.numDocs()); > + indexInfo.add("maxDoc", reader.maxDoc()); > + indexInfo.add("numTerms", numTerms ); > + indexInfo.add("version", reader.getVersion()); // TODO? Is > this different then: IndexReader.getCurrentVersion( dir )? > + indexInfo.add("optimized", reader.isOptimized() ); > + indexInfo.add("current", reader.isCurrent() ); > + indexInfo.add("hasDeletions", reader.hasDeletions() ); > + indexInfo.add("directory", dir ); > + indexInfo.add("lastModified", new Date(IndexReader.lastModified > (dir)) ); > + return indexInfo; > + } > + > + //////////////////////// SolrInfoMBeans > methods ////////////////////// > + > + @Override > + public String getDescription() { > + return "Lucene Index Browser. Inspired and modeled after > Luke: http://www.getopt.org/luke/"; > + } > + > + @Override > + public String getVersion() { > + return "$Revision: 501512 $"; > + } > + > + @Override > + public String getSourceId() { > + return "$Id: IndexInfoRequestHandler.java 487199 2006-12-14 > 13:03:40Z bdelacretaz $"; > + } > + > + @Override > + public String getSource() { > + return "$URL: https://svn.apache.org/repos/asf/lucene/solr/ > trunk/src/java/org/apache/solr/request/IndexInfoRequestHandler.java > $"; > + } > + > + @Override > + public URL[] getDocs() { > + try { > + return new URL[] { new URL("http://wiki.apache.org/solr/ > LukeRequestHandler") }; > + } > + catch( MalformedURLException ex ) { return null; } > + } > + > + /////////////////////////////////////////////////////////////////// > //////////////////// > + > + /** > + * Private internal class that counts up frequent terms > + */ > + private static class TopTermQueue extends PriorityQueue > + { > + static class TermInfo { > + TermInfo(Term t, int df) { > + term = t; > + docFreq = df; > + } > + int docFreq; > + Term term; > + } > + > + public int minFreq = 0; > + public int distinctTerms = 0; > + > + TopTermQueue(int size) { > + initialize(size); > + } > + > + @Override > + protected final boolean lessThan(Object a, Object b) { > + TermInfo termInfoA = (TermInfo)a; > + TermInfo termInfoB = (TermInfo)b; > + return termInfoA.docFreq < termInfoB.docFreq; > + } > + > + /** > + * This is a destructive call... the queue is empty at the end > + */ > + public NamedList<Integer> toNamedList( IndexSchema schema ) > + { > + // reverse the list.. > + List<TermInfo> aslist = new LinkedList<TermInfo>(); > + while( size() > 0 ) { > + aslist.add( 0, (TermInfo)pop() ); > + } > + > + NamedList<Integer> list = new NamedList<Integer>(); > + for (TermInfo i : aslist) { > + String txt = i.term.text(); > + SchemaField ft = schema.getFieldOrNull( i.term.field() ); > + if( ft != null ) { > + txt = ft.getType().indexedToReadable( txt ); > + } > + list.add( txt, i.docFreq ); > + } > + return list; > + } > + } > + > + private static Map<String,TopTermQueue> getTopTerms( IndexReader > reader, Set<String> fields, int numTerms, Set<String> junkWords ) > throws Exception > + { > + Map<String,TopTermQueue> info = new HashMap<String, > TopTermQueue>(); > + TermEnum terms = reader.terms(); > + > + while (terms.next()) { > + String field = terms.term().field(); > + String t = terms.term().text(); > + > + // Compute distinct terms for every field > + TopTermQueue tiq = info.get( field ); > + if( tiq == null ) { > + tiq = new TopTermQueue( numTerms ); > + info.put( field, tiq ); > + } > + tiq.distinctTerms++; > + > + // Only save the distinct terms for fields we worry about > + if (fields != null && fields.size() > 0) { > + if( !fields.contains( field ) ) { > + continue; > + } > + } > + if( junkWords != null && junkWords.contains( t ) ) { > + continue; > + } > + > + if( terms.docFreq() > tiq.minFreq ) { > + tiq.put(new TopTermQueue.TermInfo(terms.term(), > terms.docFreq())); > + if (tiq.size() >= numTerms) { // if tiq overfull > + tiq.pop(); // remove lowest in tiq > + tiq.minFreq = ((TopTermQueue.TermInfo)tiq.top > ()).docFreq; // reset minFreq > + } > + } > + } > + return info; > + } > +} > + > + > + > > Propchange: lucene/solr/trunk/src/java/org/apache/solr/handler/ > admin/LukeRequestHandler.java > ---------------------------------------------------------------------- > -------- > svn:eol-style = native > > Added: lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > PluginInfoHandler.java > URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/ > apache/solr/handler/admin/PluginInfoHandler.java?view=auto&rev=532975 > ====================================================================== > ======== > --- lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > PluginInfoHandler.java (added) > +++ lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > PluginInfoHandler.java Thu Apr 26 22:56:07 2007 > @@ -0,0 +1,120 @@ > +/** > + * Licensed to the Apache Software Foundation (ASF) under one or more > + * contributor license agreements. See the NOTICE file > distributed with > + * this work for additional information regarding copyright > ownership. > + * The ASF licenses this file to You under the Apache License, > Version 2.0 > + * (the "License"); you may not use this file except in compliance > with > + * the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > + * See the License for the specific language governing permissions > and > + * limitations under the License. > + */ > + > +package org.apache.solr.handler.admin; > + > +import java.net.URL; > +import java.util.ArrayList; > +import java.util.Map; > + > +import org.apache.solr.core.SolrInfoMBean; > +import org.apache.solr.core.SolrInfoRegistry; > +import org.apache.solr.handler.RequestHandlerBase; > +import org.apache.solr.handler.RequestHandlerUtils; > +import org.apache.solr.request.SolrParams; > +import org.apache.solr.request.SolrQueryRequest; > +import org.apache.solr.request.SolrQueryResponse; > +import org.apache.solr.util.SimpleOrderedMap; > + > +/** > + * similar to "admin/registry.jsp" > + * > + * NOTE: the response format is still likely to change. It should > be designed so > + * that it works nicely with an XSLT transformation. Untill we > have a nice > + * XSLT frontend for /admin, the format is still open to change. > + * > + * @author ryan > + * @version $Id$ > + * @since solr 1.2 > + */ > +public class PluginInfoHandler extends RequestHandlerBase > +{ > + @Override > + public void handleRequestBody(SolrQueryRequest req, > SolrQueryResponse rsp) throws Exception > + { > + RequestHandlerUtils.addExperimentalFormatWarning( rsp ); > + SolrParams params = req.getParams(); > + > + boolean stats = params.getBool( "stats", false ); > + rsp.add( "plugins", getSolrInfoBeans( stats ) ); > + } > + > + private static SimpleOrderedMap<Object> getSolrInfoBeans > ( boolean stats ) > + { > + SimpleOrderedMap<Object> list = new SimpleOrderedMap<Object>(); > + for (SolrInfoMBean.Category cat : SolrInfoMBean.Category.values > ()) > + { > + SimpleOrderedMap<Object> category = new > SimpleOrderedMap<Object>(); > + list.add( cat.name(), category ); > + Map<String, SolrInfoMBean> reg = SolrInfoRegistry.getRegistry > (); > + synchronized(reg) { > + for (Map.Entry<String,SolrInfoMBean> entry : reg.entrySet > ()) { > + SolrInfoMBean m = entry.getValue(); > + if (m.getCategory() != cat) continue; > + > + String na = "Not Declared"; > + SimpleOrderedMap<Object> info = new > SimpleOrderedMap<Object>(); > + category.add( entry.getKey(), info ); > + > + info.add( "name", (m.getName() !=null ? > m.getName() : na) ); > + info.add( "version", (m.getVersion() !=null ? > m.getVersion() : na) ); > + info.add( "description", (m.getDescription()!=null ? > m.getDescription() : na) ); > + > + info.add( "sourceId", (m.getSourceId() !=null ? > m.getSourceId() : na) ); > + info.add( "source", (m.getSource() !=null ? > m.getSource() : na) ); > + > + URL[] urls = m.getDocs(); > + if ((urls != null) && (urls.length > 0)) { > + ArrayList<String> docs = new ArrayList<String> > (urls.length); > + for( URL u : urls ) { > + docs.add( u.toExternalForm() ); > + } > + info.add( "docs", docs ); > + } > + > + if( stats ) { > + info.add( "stats", m.getStatistics() ); > + } > + } > + } > + } > + return list; > + } > + > + > + //////////////////////// SolrInfoMBeans > methods ////////////////////// > + > + @Override > + public String getDescription() { > + return "Registry"; > + } > + > + @Override > + public String getVersion() { > + return "$Revision: 501512 $"; > + } > + > + @Override > + public String getSourceId() { > + return "$Id: DumpRequestHandler.java 501512 2007-01-30 > 18:36:32Z yonik $"; > + } > + > + @Override > + public String getSource() { > + return "$URL: http://svn.apache.org/repos/asf/lucene/solr/ > trunk/src/java/org/apache/solr/handler/DumpRequestHandler.java $"; > + } > +} > > Propchange: lucene/solr/trunk/src/java/org/apache/solr/handler/ > admin/PluginInfoHandler.java > ---------------------------------------------------------------------- > -------- > svn:eol-style = native > > Added: lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > PropertiesRequestHandler.java > URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/ > apache/solr/handler/admin/PropertiesRequestHandler.java? > view=auto&rev=532975 > ====================================================================== > ======== > --- lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > PropertiesRequestHandler.java (added) > +++ lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > PropertiesRequestHandler.java Thu Apr 26 22:56:07 2007 > @@ -0,0 +1,73 @@ > +/** > + * Licensed to the Apache Software Foundation (ASF) under one or more > + * contributor license agreements. See the NOTICE file > distributed with > + * this work for additional information regarding copyright > ownership. > + * The ASF licenses this file to You under the Apache License, > Version 2.0 > + * (the "License"); you may not use this file except in compliance > with > + * the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > + * See the License for the specific language governing permissions > and > + * limitations under the License. > + */ > + > +package org.apache.solr.handler.admin; > + > +import java.io.IOException; > + > +import org.apache.solr.handler.RequestHandlerBase; > +import org.apache.solr.request.SolrQueryRequest; > +import org.apache.solr.request.SolrQueryResponse; > +import org.apache.solr.util.SimpleOrderedMap; > + > +/** > + * @author ryan > + * @version $Id$ > + * @since solr 1.2 > + */ > +public class PropertiesRequestHandler extends RequestHandlerBase > +{ > + @Override > + public void handleRequestBody(SolrQueryRequest req, > SolrQueryResponse rsp) throws IOException > + { > + SimpleOrderedMap<String> props = new SimpleOrderedMap<String>(); > + String name = req.getParams().get( "name" ); > + if( name != null ) { > + props.add( name, System.getProperty(name) ); > + } > + else { > + java.util.Enumeration e = System.getProperties > ().propertyNames(); > + while(e.hasMoreElements()) { > + String prop = (String)e.nextElement(); > + props.add( prop, System.getProperty(prop) ); > + } > + } > + rsp.add( "system.properties", props ); > + } > + > + //////////////////////// SolrInfoMBeans > methods ////////////////////// > + > + @Override > + public String getDescription() { > + return "Get System Properties"; > + } > + > + @Override > + public String getVersion() { > + return "$Revision: 501512 $"; > + } > + > + @Override > + public String getSourceId() { > + return "$Id: DumpRequestHandler.java 501512 2007-01-30 > 18:36:32Z yonik $"; > + } > + > + @Override > + public String getSource() { > + return "$URL: http://svn.apache.org/repos/asf/lucene/solr/ > trunk/src/java/org/apache/solr/handler/DumpRequestHandler.java $"; > + } > +} > > Propchange: lucene/solr/trunk/src/java/org/apache/solr/handler/ > admin/PropertiesRequestHandler.java > ---------------------------------------------------------------------- > -------- > svn:eol-style = native > > Added: lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > SystemInfoHandler.java > URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/ > apache/solr/handler/admin/SystemInfoHandler.java?view=auto&rev=532975 > ====================================================================== > ======== > --- lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > SystemInfoHandler.java (added) > +++ lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > SystemInfoHandler.java Thu Apr 26 22:56:07 2007 > @@ -0,0 +1,299 @@ > +/** > + * Licensed to the Apache Software Foundation (ASF) under one or more > + * contributor license agreements. See the NOTICE file > distributed with > + * this work for additional information regarding copyright > ownership. > + * The ASF licenses this file to You under the Apache License, > Version 2.0 > + * (the "License"); you may not use this file except in compliance > with > + * the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > + * See the License for the specific language governing permissions > and > + * limitations under the License. > + */ > + > +package org.apache.solr.handler.admin; > + > +import java.io.BufferedReader; > +import java.io.DataInputStream; > +import java.io.File; > +import java.io.StringWriter; > +import java.lang.management.ManagementFactory; > +import java.lang.management.OperatingSystemMXBean; > +import java.lang.management.RuntimeMXBean; > +import java.lang.reflect.Method; > +import java.net.InetAddress; > +import java.util.Date; > + > +import org.apache.commons.io.FileUtils; > +import org.apache.commons.io.IOUtils; > +import org.apache.lucene.LucenePackage; > +import org.apache.solr.core.Config; > +import org.apache.solr.core.SolrCore; > +import org.apache.solr.handler.RequestHandlerBase; > +import org.apache.solr.handler.RequestHandlerUtils; > +import org.apache.solr.request.SolrQueryRequest; > +import org.apache.solr.request.SolrQueryResponse; > +import org.apache.solr.schema.IndexSchema; > +import org.apache.solr.util.NamedList; > +import org.apache.solr.util.SimpleOrderedMap; > +import org.apache.solr.util.XML; > + > + > +/** > + * This handler returns system info > + * > + * NOTE: the response format is still likely to change. It should > be designed so > + * that it works nicely with an XSLT transformation. Untill we > have a nice > + * XSLT frontend for /admin, the format is still open to change. > + * > + * @author ryan > + * @version $Id$ > + * @since solr 1.2 > + */ > +public class SystemInfoHandler extends RequestHandlerBase > +{ > + @Override > + public void handleRequestBody(SolrQueryRequest req, > SolrQueryResponse rsp) throws Exception > + { > + RequestHandlerUtils.addExperimentalFormatWarning( rsp ); > + > + rsp.add( "core", getCoreInfo( req.getCore() ) ); > + rsp.add( "lucene", getLuceneInfo() ); > + rsp.add( "jvm", getJvmInfo() ); > + rsp.add( "system", getSystemInfo() ); > + } > + > + /** > + * Get system info > + */ > + private static SimpleOrderedMap<Object> getCoreInfo( SolrCore > core ) throws Exception > + { > + SimpleOrderedMap<Object> info = new SimpleOrderedMap<Object>(); > + > + IndexSchema schema = core.getSchema(); > + info.add( "schema", schema != null ? schema.getName():"no > schema!" ); > + > + // Host > + InetAddress addr = InetAddress.getLocalHost(); > + info.add( "host", addr.getCanonicalHostName() ); > + > + // Now > + info.add( "now", new Date() ); > + > + // Start Time > + info.add( "start", new Date(core.getStartTime()) ); > + > + // Solr Home > + SimpleOrderedMap<Object> dirs = new SimpleOrderedMap<Object>(); > + dirs.add( "instance", new File( Config.getInstanceDir > () ).getAbsolutePath() ); > + dirs.add( "data", new File( core.getDataDir() ).getAbsolutePath > () ); > + dirs.add( "index", new File( core.getIndexDir > () ).getAbsolutePath() ); > + info.add( "directory", dirs ); > + return info; > + } > + > + /** > + * Get system info > + */ > + private static SimpleOrderedMap<Object> getSystemInfo() throws > Exception > + { > + SimpleOrderedMap<Object> info = new SimpleOrderedMap<Object>(); > + > + OperatingSystemMXBean os = > ManagementFactory.getOperatingSystemMXBean(); > + info.add( "name", os.getName() ); > + info.add( "version", os.getVersion() ); > + info.add( "arch", os.getArch() ); > + > + // Java 1.6 > + addGetterIfAvaliable( os, "systemLoadAverage", info ); > + > + // com.sun.management.UnixOperatingSystemMXBean > + addGetterIfAvaliable( os, "openFileDescriptorCount", info ); > + addGetterIfAvaliable( os, "maxFileDescriptorCount", info ); > + > + // com.sun.management.OperatingSystemMXBean > + addGetterIfAvaliable( os, "committedVirtualMemorySize", info ); > + addGetterIfAvaliable( os, "totalPhysicalMemorySize", info ); > + addGetterIfAvaliable( os, "totalSwapSpaceSize", info ); > + addGetterIfAvaliable( os, "processCpuTime", info ); > + > + try { > + if( !os.getName().toLowerCase().startsWith( "windows" ) ) { > + // Try some command line things > + info.add( "uname", execute( "uname -a" ) ); > + info.add( "ulimit", execute( "ulimit -n" ) ); > + info.add( "uptime", execute( "uptime" ) ); > + } > + } > + catch( Throwable ex ) {} // ignore > + return info; > + } > + > + /** > + * Try to run a getter function. This is usefull because java > 1.6 has a few extra > + * usefull functions on the <code>OperatingSystemMXBean</code> > + * > + * If you are running a sun jvm, there are nice functions in: > + * UnixOperatingSystemMXBean and > com.sun.management.OperatingSystemMXBean > + * > + * it is package protected so it can be tested... > + */ > + static void addGetterIfAvaliable( Object obj, String getter, > NamedList<Object> info ) > + { > + // This is a 1.6 functon, so lets do a little magic to *try* > to make it work > + try { > + String n = Character.toUpperCase( getter.charAt(0) ) + > getter.substring( 1 ); > + Method m = obj.getClass().getMethod( "get" + n ); > + Object v = m.invoke( obj, (Object[])null ); > + if( v != null ) { > + info.add( getter, v ); > + } > + } > + catch( Exception ex ) {} // don't worry, this only works for 1.6 > + } > + > + > + /** > + * Utility function to execute a funciton > + */ > + private static String execute( String cmd ) > + { > + DataInputStream in = null; > + BufferedReader reader = null; > + > + try { > + Process process = Runtime.getRuntime().exec(cmd); > + in = new DataInputStream( process.getInputStream() ); > + return IOUtils.toString( in ); > + } > + catch( Exception ex ) { > + ex.printStackTrace(); > + return "(error executing: " + cmd + ")"; > + } > + finally { > + IOUtils.closeQuietly( reader ); > + IOUtils.closeQuietly( in ); > + } > + } > + > + /** > + * Get JVM Info - including memory info > + */ > + private static SimpleOrderedMap<Object> getJvmInfo() > + { > + SimpleOrderedMap<Object> jvm = new SimpleOrderedMap<Object>(); > + jvm.add( "version", System.getProperty("java.vm.version") ); > + jvm.add( "name", System.getProperty("java.vm.name") ); > + > + Runtime runtime = Runtime.getRuntime(); > + jvm.add( "processors", runtime.availableProcessors() ); > + > + long used = runtime.totalMemory() - runtime.freeMemory(); > + int percentUsed = (int)(((double)(used)/(double) > runtime.maxMemory())*100); > + > + > + SimpleOrderedMap<Object> mem = new SimpleOrderedMap<Object>(); > + mem.add( "free", FileUtils.byteCountToDisplaySize > ( runtime.freeMemory() ) ); > + mem.add( "total", FileUtils.byteCountToDisplaySize > ( runtime.totalMemory() ) ); > + mem.add( "max", FileUtils.byteCountToDisplaySize > ( runtime.maxMemory() ) ); > + mem.add( "used", FileUtils.byteCountToDisplaySize( used ) + > " (%"+percentUsed+")"); > + jvm.add( "memory", mem ); > + > + // JMX properties -- probably should be moved to a different > handler > + SimpleOrderedMap<Object> jmx = new SimpleOrderedMap<Object>(); > + try{ > + RuntimeMXBean mx = ManagementFactory.getRuntimeMXBean(); > + jmx.add( "bootclasspath", mx.getBootClassPath()); > + jmx.add( "classpath", mx.getClassPath() ); > + > + // the input arguments passed to the Java virtual machine > + // which does not include the arguments to the main method. > + jmx.add( "commandLineArgs", mx.getInputArguments()); > + // a map of names and values of all system properties. > + //jmx.add( "SYSTEM PROPERTIES", mx.getSystemProperties()); > + > + jmx.add( "startTime", new Date(mx.getStartTime())); > + jmx.add( "upTimeMS", mx.getUptime() ); > + } > + catch (Exception e) { > + e.printStackTrace(); > + } > + jvm.add( "jmx", jmx ); > + return jvm; > + } > + > + private static SimpleOrderedMap<Object> getLuceneInfo() throws > Exception > + { > + SimpleOrderedMap<Object> info = new SimpleOrderedMap<Object>(); > + > + String solrImplVersion = ""; > + String solrSpecVersion = ""; > + String luceneImplVersion = ""; > + String luceneSpecVersion = ""; > + > + // --- > + Package p = SolrCore.class.getPackage(); > + StringWriter tmp = new StringWriter(); > + solrImplVersion = p.getImplementationVersion(); > + if (null != solrImplVersion) { > + XML.escapeCharData(solrImplVersion, tmp); > + solrImplVersion = tmp.toString(); > + } > + tmp = new StringWriter(); > + solrSpecVersion = p.getSpecificationVersion() ; > + if (null != solrSpecVersion) { > + XML.escapeCharData(solrSpecVersion, tmp); > + solrSpecVersion = tmp.toString(); > + } > + > + p = LucenePackage.class.getPackage(); > + tmp = new StringWriter(); > + luceneImplVersion = p.getImplementationVersion(); > + if (null != luceneImplVersion) { > + XML.escapeCharData(luceneImplVersion, tmp); > + luceneImplVersion = tmp.toString(); > + } > + tmp = new StringWriter(); > + luceneSpecVersion = p.getSpecificationVersion() ; > + if (null != luceneSpecVersion) { > + XML.escapeCharData(luceneSpecVersion, tmp); > + luceneSpecVersion = tmp.toString(); > + } > + > + // Add it to the list > + info.add( "solr-spec-version", solrSpecVersion ); > + info.add( "solr-impl-version", solrImplVersion ); > + info.add( "lucene-spec-version", luceneSpecVersion ); > + info.add( "lucene-impl-version", luceneImplVersion ); > + return info; > + } > + > + //////////////////////// SolrInfoMBeans > methods ////////////////////// > + > + @Override > + public String getDescription() { > + return "Get System Info"; > + } > + > + @Override > + public String getVersion() { > + return "$Revision: 501512 $"; > + } > + > + @Override > + public String getSourceId() { > + return "$Id: IndexInfoRequestHandler.java 487199 2006-12-14 > 13:03:40Z bdelacretaz $"; > + } > + > + @Override > + public String getSource() { > + return "$URL: https://svn.apache.org/repos/asf/lucene/solr/ > trunk/src/java/org/apache/solr/request/IndexInfoRequestHandler.java > $"; > + } > +} > + > + > + > > Propchange: lucene/solr/trunk/src/java/org/apache/solr/handler/ > admin/SystemInfoHandler.java > ---------------------------------------------------------------------- > -------- > svn:eol-style = native > > Added: lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > ThreadDumpHandler.java > URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/ > apache/solr/handler/admin/ThreadDumpHandler.java?view=auto&rev=532975 > ====================================================================== > ======== > --- lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > ThreadDumpHandler.java (added) > +++ lucene/solr/trunk/src/java/org/apache/solr/handler/admin/ > ThreadDumpHandler.java Thu Apr 26 22:56:07 2007 > @@ -0,0 +1,152 @@ > +/** > + * Licensed to the Apache Software Foundation (ASF) under one or more > + * contributor license agreements. See the NOTICE file > distributed with > + * this work for additional information regarding copyright > ownership. > + * The ASF licenses this file to You under the Apache License, > Version 2.0 > + * (the "License"); you may not use this file except in compliance > with > + * the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > + * See the License for the specific language governing permissions > and > + * limitations under the License. > + */ > + > +package org.apache.solr.handler.admin; > + > +import java.io.IOException; > +import java.lang.management.ManagementFactory; > +import java.lang.management.ThreadInfo; > +import java.lang.management.ThreadMXBean; > + > +import org.apache.solr.handler.RequestHandlerBase; > +import org.apache.solr.handler.RequestHandlerUtils; > +import org.apache.solr.request.SolrQueryRequest; > +import org.apache.solr.request.SolrQueryResponse; > +import org.apache.solr.util.NamedList; > +import org.apache.solr.util.SimpleOrderedMap; > + > +/** > + * Copied from "admin/threaddump.jsp" > + * > + * NOTE: the response format is still likely to change. It should > be designed so > + * that it works nicely with an XSLT transformation. Untill we > have a nice > + * XSLT frontend for /admin, the format is still open to change. > + * > + * @author ryan > + * @version $Id$ > + * @since solr 1.2 > + */ > +public class ThreadDumpHandler extends RequestHandlerBase > +{ > + @Override > + public void handleRequestBody(SolrQueryRequest req, > SolrQueryResponse rsp) throws IOException > + { > + RequestHandlerUtils.addExperimentalFormatWarning( rsp ); > + > + SimpleOrderedMap<Object> system = new SimpleOrderedMap<Object>(); > + rsp.add( "system", system ); > + > + ThreadMXBean tmbean = ManagementFactory.getThreadMXBean(); > + > + // Thread Count > + SimpleOrderedMap<Object> nl = new SimpleOrderedMap<Object>(); > + nl.add( "current",tmbean.getThreadCount() ); > + nl.add( "peak", tmbean.getPeakThreadCount() ); > + nl.add( "daemon", tmbean.getDaemonThreadCount() ); > + system.add( "threadCount", nl ); > + > + // Deadlocks > + ThreadInfo[] tinfos; > + long[] tids = tmbean.findMonitorDeadlockedThreads(); > + if (tids != null) { > + tinfos = tmbean.getThreadInfo(tids, Integer.MAX_VALUE); > + NamedList<SimpleOrderedMap<Object>> lst = new > NamedList<SimpleOrderedMap<Object>>(); > + for (ThreadInfo ti : tinfos) { > + lst.add( "thread", getThreadInfo( ti, tmbean ) ); > + } > + system.add( "deadlocks", lst ); > + } > + > + // Now show all the threads.... > + tids = tmbean.getAllThreadIds(); > + tinfos = tmbean.getThreadInfo(tids, Integer.MAX_VALUE); > + NamedList<SimpleOrderedMap<Object>> lst = new > NamedList<SimpleOrderedMap<Object>>(); > + for (ThreadInfo ti : tinfos) { > + lst.add( "thread", getThreadInfo( ti, tmbean ) ); > + } > + system.add( "threadDump", lst ); > + } > + > + //----------------------------------------------------------------- > --------------- > + //----------------------------------------------------------------- > --------------- > + > + private static SimpleOrderedMap<Object> getThreadInfo > ( ThreadInfo ti, ThreadMXBean tmbean ) throws IOException > + { > + SimpleOrderedMap<Object> info = new SimpleOrderedMap<Object>(); > + long tid = ti.getThreadId(); > + > + info.add( "id", tid ); > + info.add( "name", ti.getThreadName() ); > + info.add( "state", ti.getThreadState().toString() ); > + > + if (ti.getLockName() != null) { > + info.add( "lock", ti.getLockName() ); > + } > + if (ti.isSuspended()) { > + info.add( "suspended", true ); > + } > + if (ti.isInNative()) { > + info.add( "native", true ); > + } > + > + if (tmbean.isThreadCpuTimeSupported()) { > + info.add( "cpuTime", formatNanos(tmbean.getThreadCpuTime > (tid)) ); > + info.add( "userTime", formatNanos(tmbean.getThreadUserTime > (tid)) ); > + } > + > + if (ti.getLockOwnerName() != null) { > + SimpleOrderedMap<Object> owner = new SimpleOrderedMap<Object> > (); > + owner.add( "name", ti.getLockOwnerName() ); > + owner.add( "id", ti.getLockOwnerId() ); > + } > + > + // Add the stack trace > + int i=0; > + String[] trace = new String[ti.getStackTrace().length]; > + for( StackTraceElement ste : ti.getStackTrace()) { > + trace[i++] = ste.toString(); > + } > + info.add( "stackTrace", trace ); > + return info; > + } > + > + private static String formatNanos(long ns) { > + return String.format("%.4fms", ns / (double) 1000000); > + } > + > + //////////////////////// SolrInfoMBeans > methods ////////////////////// > + > + @Override > + public String getDescription() { > + return "Thread Dump"; > + } > + > + @Override > + public String getVersion() { > + return "$Revision: 501512 $"; > + } > + > + @Override > + public String getSourceId() { > + return "$Id: DumpRequestHandler.java 501512 2007-01-30 > 18:36:32Z yonik $"; > + } > + > + @Override > + public String getSource() { > + return "$URL: http://svn.apache.org/repos/asf/lucene/solr/ > trunk/src/java/org/apache/solr/handler/DumpRequestHandler.java $"; > + } > +} > > Propchange: lucene/solr/trunk/src/java/org/apache/solr/handler/ > admin/ThreadDumpHandler.java > ---------------------------------------------------------------------- > -------- > svn:eol-style = native > > Added: lucene/solr/trunk/src/test/org/apache/solr/handler/admin/ > SystemInfoHandlerTest.java > URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/test/org/ > apache/solr/handler/admin/SystemInfoHandlerTest.java? > view=auto&rev=532975 > ====================================================================== > ======== > --- lucene/solr/trunk/src/test/org/apache/solr/handler/admin/ > SystemInfoHandlerTest.java (added) > +++ lucene/solr/trunk/src/test/org/apache/solr/handler/admin/ > SystemInfoHandlerTest.java Thu Apr 26 22:56:07 2007 > @@ -0,0 +1,50 @@ > +/** > + * Licensed to the Apache Software Foundation (ASF) under one or more > + * contributor license agreements. See the NOTICE file > distributed with > + * this work for additional information regarding copyright > ownership. > + * The ASF licenses this file to You under the Apache License, > Version 2.0 > + * (the "License"); you may not use this file except in compliance > with > + * the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > + * See the License for the specific language governing permissions > and > + * limitations under the License. > + */ > + > +package org.apache.solr.handler.admin; > + > +import java.lang.management.ManagementFactory; > +import java.lang.management.OperatingSystemMXBean; > + > +import junit.framework.TestCase; > + > +import org.apache.solr.util.SimpleOrderedMap; > + > + > +public class SystemInfoHandlerTest extends TestCase { > + > + public void testMagickGetter() { > + > + OperatingSystemMXBean os = > ManagementFactory.getOperatingSystemMXBean(); > + > + // make one directly > + SimpleOrderedMap<Object> info = new SimpleOrderedMap<Object>(); > + info.add( "name", os.getName() ); > + info.add( "version", os.getVersion() ); > + info.add( "arch", os.getArch() ); > + > + // make another using addGetterIfAvaliable > + SimpleOrderedMap<Object> info2 = new SimpleOrderedMap<Object>(); > + SystemInfoHandler.addGetterIfAvaliable( os, "name", info2 ); > + SystemInfoHandler.addGetterIfAvaliable( os, "version", info2 ); > + SystemInfoHandler.addGetterIfAvaliable( os, "arch", info2 ); > + > + // make sure they got the same thing > + assertEquals( info.toString(), info2.toString() ); > + } > + > +} > > Propchange: lucene/solr/trunk/src/test/org/apache/solr/handler/ > admin/SystemInfoHandlerTest.java > ---------------------------------------------------------------------- > -------- > svn:eol-style = native >
|