001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.solr.handler.admin;
017:
018: import java.io.BufferedReader;
019: import java.io.DataInputStream;
020: import java.io.File;
021: import java.io.StringWriter;
022: import java.lang.management.ManagementFactory;
023: import java.lang.management.OperatingSystemMXBean;
024: import java.lang.management.RuntimeMXBean;
025: import java.lang.reflect.Method;
026: import java.net.InetAddress;
027: import java.util.Date;
028:
029: import org.apache.commons.io.FileUtils;
030: import org.apache.commons.io.IOUtils;
031: import org.apache.lucene.LucenePackage;
032: import org.apache.solr.core.Config;
033: import org.apache.solr.core.SolrCore;
034: import org.apache.solr.handler.RequestHandlerBase;
035: import org.apache.solr.handler.RequestHandlerUtils;
036: import org.apache.solr.request.SolrQueryRequest;
037: import org.apache.solr.request.SolrQueryResponse;
038: import org.apache.solr.schema.IndexSchema;
039: import org.apache.solr.util.NamedList;
040: import org.apache.solr.util.SimpleOrderedMap;
041: import org.apache.solr.util.XML;
042:
043: /**
044: * This handler returns system info
045: *
046: * NOTE: the response format is still likely to change. It should be designed so
047: * that it works nicely with an XSLT transformation. Until we have a nice
048: * XSLT front end for /admin, the format is still open to change.
049: *
050: * @author ryan
051: * @version $Id: SystemInfoHandler.java 533815 2007-04-30 17:57:52Z ryan $
052: * @since solr 1.2
053: */
054: public class SystemInfoHandler extends RequestHandlerBase {
055: @Override
056: public void handleRequestBody(SolrQueryRequest req,
057: SolrQueryResponse rsp) throws Exception {
058: RequestHandlerUtils.addExperimentalFormatWarning(rsp);
059:
060: rsp.add("core", getCoreInfo(req.getCore()));
061: rsp.add("lucene", getLuceneInfo());
062: rsp.add("jvm", getJvmInfo());
063: rsp.add("system", getSystemInfo());
064: }
065:
066: /**
067: * Get system info
068: */
069: private static SimpleOrderedMap<Object> getCoreInfo(SolrCore core)
070: throws Exception {
071: SimpleOrderedMap<Object> info = new SimpleOrderedMap<Object>();
072:
073: IndexSchema schema = core.getSchema();
074: info.add("schema", schema != null ? schema.getName()
075: : "no schema!");
076:
077: // Host
078: InetAddress addr = InetAddress.getLocalHost();
079: info.add("host", addr.getCanonicalHostName());
080:
081: // Now
082: info.add("now", new Date());
083:
084: // Start Time
085: info.add("start", new Date(core.getStartTime()));
086:
087: // Solr Home
088: SimpleOrderedMap<Object> dirs = new SimpleOrderedMap<Object>();
089: dirs.add("instance", new File(Config.getInstanceDir())
090: .getAbsolutePath());
091: dirs.add("data", new File(core.getDataDir()).getAbsolutePath());
092: dirs.add("index", new File(core.getIndexDir())
093: .getAbsolutePath());
094: info.add("directory", dirs);
095: return info;
096: }
097:
098: /**
099: * Get system info
100: */
101: private static SimpleOrderedMap<Object> getSystemInfo()
102: throws Exception {
103: SimpleOrderedMap<Object> info = new SimpleOrderedMap<Object>();
104:
105: OperatingSystemMXBean os = ManagementFactory
106: .getOperatingSystemMXBean();
107: info.add("name", os.getName());
108: info.add("version", os.getVersion());
109: info.add("arch", os.getArch());
110:
111: // Java 1.6
112: addGetterIfAvaliable(os, "systemLoadAverage", info);
113:
114: // com.sun.management.UnixOperatingSystemMXBean
115: addGetterIfAvaliable(os, "openFileDescriptorCount", info);
116: addGetterIfAvaliable(os, "maxFileDescriptorCount", info);
117:
118: // com.sun.management.OperatingSystemMXBean
119: addGetterIfAvaliable(os, "committedVirtualMemorySize", info);
120: addGetterIfAvaliable(os, "totalPhysicalMemorySize", info);
121: addGetterIfAvaliable(os, "totalSwapSpaceSize", info);
122: addGetterIfAvaliable(os, "processCpuTime", info);
123:
124: try {
125: if (!os.getName().toLowerCase().startsWith("windows")) {
126: // Try some command line things
127: info.add("uname", execute("uname -a"));
128: info.add("ulimit", execute("ulimit -n"));
129: info.add("uptime", execute("uptime"));
130: }
131: } catch (Throwable ex) {
132: } // ignore
133: return info;
134: }
135:
136: /**
137: * Try to run a getter function. This is usefull because java 1.6 has a few extra
138: * usefull functions on the <code>OperatingSystemMXBean</code>
139: *
140: * If you are running a sun jvm, there are nice functions in:
141: * UnixOperatingSystemMXBean and com.sun.management.OperatingSystemMXBean
142: *
143: * it is package protected so it can be tested...
144: */
145: static void addGetterIfAvaliable(Object obj, String getter,
146: NamedList<Object> info) {
147: // This is a 1.6 functon, so lets do a little magic to *try* to make it work
148: try {
149: String n = Character.toUpperCase(getter.charAt(0))
150: + getter.substring(1);
151: Method m = obj.getClass().getMethod("get" + n);
152: Object v = m.invoke(obj, (Object[]) null);
153: if (v != null) {
154: info.add(getter, v);
155: }
156: } catch (Exception ex) {
157: } // don't worry, this only works for 1.6
158: }
159:
160: /**
161: * Utility function to execute a funciton
162: */
163: private static String execute(String cmd) {
164: DataInputStream in = null;
165: BufferedReader reader = null;
166:
167: try {
168: Process process = Runtime.getRuntime().exec(cmd);
169: in = new DataInputStream(process.getInputStream());
170: return IOUtils.toString(in);
171: } catch (Exception ex) {
172: ex.printStackTrace();
173: return "(error executing: " + cmd + ")";
174: } finally {
175: IOUtils.closeQuietly(reader);
176: IOUtils.closeQuietly(in);
177: }
178: }
179:
180: /**
181: * Get JVM Info - including memory info
182: */
183: private static SimpleOrderedMap<Object> getJvmInfo() {
184: SimpleOrderedMap<Object> jvm = new SimpleOrderedMap<Object>();
185: jvm.add("version", System.getProperty("java.vm.version"));
186: jvm.add("name", System.getProperty("java.vm.name"));
187:
188: Runtime runtime = Runtime.getRuntime();
189: jvm.add("processors", runtime.availableProcessors());
190:
191: long used = runtime.totalMemory() - runtime.freeMemory();
192: int percentUsed = (int) (((double) (used) / (double) runtime
193: .maxMemory()) * 100);
194:
195: SimpleOrderedMap<Object> mem = new SimpleOrderedMap<Object>();
196: mem.add("free", FileUtils.byteCountToDisplaySize(runtime
197: .freeMemory()));
198: mem.add("total", FileUtils.byteCountToDisplaySize(runtime
199: .totalMemory()));
200: mem.add("max", FileUtils.byteCountToDisplaySize(runtime
201: .maxMemory()));
202: mem.add("used", FileUtils.byteCountToDisplaySize(used) + " (%"
203: + percentUsed + ")");
204: jvm.add("memory", mem);
205:
206: // JMX properties -- probably should be moved to a different handler
207: SimpleOrderedMap<Object> jmx = new SimpleOrderedMap<Object>();
208: try {
209: RuntimeMXBean mx = ManagementFactory.getRuntimeMXBean();
210: jmx.add("bootclasspath", mx.getBootClassPath());
211: jmx.add("classpath", mx.getClassPath());
212:
213: // the input arguments passed to the Java virtual machine
214: // which does not include the arguments to the main method.
215: jmx.add("commandLineArgs", mx.getInputArguments());
216: // a map of names and values of all system properties.
217: //jmx.add( "SYSTEM PROPERTIES", mx.getSystemProperties());
218:
219: jmx.add("startTime", new Date(mx.getStartTime()));
220: jmx.add("upTimeMS", mx.getUptime());
221: } catch (Exception e) {
222: e.printStackTrace();
223: }
224: jvm.add("jmx", jmx);
225: return jvm;
226: }
227:
228: private static SimpleOrderedMap<Object> getLuceneInfo()
229: throws Exception {
230: SimpleOrderedMap<Object> info = new SimpleOrderedMap<Object>();
231:
232: String solrImplVersion = "";
233: String solrSpecVersion = "";
234: String luceneImplVersion = "";
235: String luceneSpecVersion = "";
236:
237: // ---
238: Package p = SolrCore.class.getPackage();
239: StringWriter tmp = new StringWriter();
240: solrImplVersion = p.getImplementationVersion();
241: if (null != solrImplVersion) {
242: XML.escapeCharData(solrImplVersion, tmp);
243: solrImplVersion = tmp.toString();
244: }
245: tmp = new StringWriter();
246: solrSpecVersion = p.getSpecificationVersion();
247: if (null != solrSpecVersion) {
248: XML.escapeCharData(solrSpecVersion, tmp);
249: solrSpecVersion = tmp.toString();
250: }
251:
252: p = LucenePackage.class.getPackage();
253: tmp = new StringWriter();
254: luceneImplVersion = p.getImplementationVersion();
255: if (null != luceneImplVersion) {
256: XML.escapeCharData(luceneImplVersion, tmp);
257: luceneImplVersion = tmp.toString();
258: }
259: tmp = new StringWriter();
260: luceneSpecVersion = p.getSpecificationVersion();
261: if (null != luceneSpecVersion) {
262: XML.escapeCharData(luceneSpecVersion, tmp);
263: luceneSpecVersion = tmp.toString();
264: }
265:
266: // Add it to the list
267: info.add("solr-spec-version", solrSpecVersion);
268: info.add("solr-impl-version", solrImplVersion);
269: info.add("lucene-spec-version", luceneSpecVersion);
270: info.add("lucene-impl-version", luceneImplVersion);
271: return info;
272: }
273:
274: //////////////////////// SolrInfoMBeans methods //////////////////////
275:
276: @Override
277: public String getDescription() {
278: return "Get System Info";
279: }
280:
281: @Override
282: public String getVersion() {
283: return "$Revision: 533815 $";
284: }
285:
286: @Override
287: public String getSourceId() {
288: return "$Id: SystemInfoHandler.java 533815 2007-04-30 17:57:52Z ryan $";
289: }
290:
291: @Override
292: public String getSource() {
293: return "$URL: https://svn.apache.org/repos/asf/lucene/solr/branches/branch-1.2/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java $";
294: }
295: }
|