Java tutorial
/* * $HeadURL$ * $Id$ * Copyright (c) 2006-2012 by Public Library of Science http://plos.org http://ambraproject.org * 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.0Unless 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.ambraproject.action.debug; import org.ambraproject.action.InternalIpAction; import org.ambraproject.filestore.FileStoreService; import org.ambraproject.web.SessionCounter; import org.apache.commons.configuration.Configuration; import org.apache.commons.io.IOUtils; import org.apache.struts2.ServletActionContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.ambraproject.configuration.ConfigurationStore; import javax.naming.Context; import javax.naming.InitialContext; import javax.servlet.http.HttpServletRequest; import javax.sql.DataSource; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.util.Date; import java.util.Enumeration; import java.util.Iterator; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Action class that gathers a bunch of debugging information about a running * ambra instance. */ public class DebugInfoAction extends InternalIpAction { private static final Logger log = LoggerFactory.getLogger(DebugInfoAction.class); private Date timestamp; private String host; private String hostIp; private String buildInfo; private double jvmFreeMemory; private double jvmTotalMemory; private double jvmMaxMemory; private String tomcatVersion; private int sessionCount; private String configuration; private String dbUrl; private String dbUser; private String solrUrl; private String filestore; private String cmdLine; @Override public String execute() throws Exception { if (!checkAccess()) { return ERROR; } timestamp = new Date(System.currentTimeMillis()); Runtime rt = Runtime.getRuntime(); jvmFreeMemory = (double) rt.freeMemory() / (1024.0 * 1024.0); jvmTotalMemory = (double) rt.totalMemory() / (1024.0 * 1024.0); jvmMaxMemory = (double) rt.maxMemory() / (1024.0 * 1024.0); HttpServletRequest req = ServletActionContext.getRequest(); tomcatVersion = ServletActionContext.getServletContext().getServerInfo(); sessionCount = SessionCounter.getSessionCount(); host = req.getLocalName(); hostIp = req.getLocalAddr(); buildInfo = generateBuildInfo(); // The easiest way I found to get the URL and username for the DB. // It's not that easy and involves opening a connection... Context initialContext = new InitialContext(); Context context = (Context) initialContext.lookup("java:comp/env"); DataSource ds = (DataSource) context.lookup("jdbc/AmbraDS"); Connection conn = null; try { conn = ds.getConnection(); DatabaseMetaData metadata = conn.getMetaData(); dbUrl = metadata.getURL(); dbUser = metadata.getUserName(); } finally { conn.close(); } Configuration config = ConfigurationStore.getInstance().getConfiguration(); FileStoreService filestoreService = (FileStoreService) context.lookup("ambra/FileStore"); filestore = filestoreService.toString(); solrUrl = (String) config.getProperty("ambra.services.search.server.url"); configuration = dumpConfig(config); cmdLine = IOUtils.toString(new FileInputStream("/proc/self/cmdline")); return SUCCESS; } /** * Reads a file from the ambra-base .jar in the classpath. * * @param path filepath, relative to the jar * @return contents of the file, or null if it was not found * @throws IOException */ private String readFileFromAmbraJar(String path) throws IOException { // Scan through all such files in the classpath, and pull out the one // associated with the ambra-base .jar. URL url = null; for (Enumeration<URL> manifests = Thread.currentThread().getContextClassLoader() .getResources(path); manifests.hasMoreElements();) { url = manifests.nextElement(); if (url.getFile().contains("/ambra-base-")) { break; } } InputStream is = url.openStream(); String result = null; try { result = IOUtils.toString(is); } finally { is.close(); } return result; } private static final Pattern YEAR_PATTERN = Pattern.compile("#.+20\\d{2}$"); /** * Generates an informative message describing who built the application and when. */ private String generateBuildInfo() throws IOException { String manifest = readFileFromAmbraJar("META-INF/MANIFEST.MF"); String builder = null; if (manifest != null) { for (String line : manifest.split("\n")) { if (line != null && line.startsWith("Built-By:")) { builder = line.substring("Built-By:".length()).trim(); break; } } } String properties = readFileFromAmbraJar("META-INF/maven/org.ambraproject/ambra-base/pom.properties"); String buildDate = null; String version = null; if (properties != null) { for (String line : properties.split("\n")) { // Currently maven puts the build date on the second line, prepended // with a #. Look for anything that vaguely resembles a date. Matcher match = YEAR_PATTERN.matcher(line); if (match.matches()) { buildDate = line.substring(1).trim(); } else { if (line != null && line.startsWith("version=")) { version = line.substring("version=".length()).trim(); } } } } builder = builder == null ? "" : "by " + builder; buildDate = buildDate == null ? "" : "on " + buildDate; version = version == null ? "" : String.format("(%s)", version); return String.format("Built %s %s %s", builder, buildDate, version); } /** * Returns a string with information about many of the ambra.* properties * in a Configuration. Intended to be informational-only, not exhaustive. */ private String dumpConfig(Configuration config) { StringBuilder result = new StringBuilder(); Iterator iter = config.getKeys(); while (iter.hasNext()) { String key = (String) iter.next(); // Don't display the virtual journal stuff; it's long and not particularly useful. if (key.startsWith("ambra.") && !key.startsWith("ambra.virtualJournals.")) { Object value = config.getProperty(key); // Attempt to dereference other properties referred to by "${foo}" notation. if (value instanceof String) { String valueStr = (String) value; if (valueStr.startsWith("${")) { String refKey = valueStr.substring(2, valueStr.length() - 1); Object refValue = config.getProperty(refKey); if (refValue != null) { value = String.format("%s -> %s", valueStr, refValue); } } } result.append(key).append(": ").append(value).append('\n'); } } return result.toString(); } public Date getTimestamp() { return timestamp; } public String getHost() { return host; } public String getHostIp() { return hostIp; } public String getBuildInfo() { return buildInfo; } public double getJvmFreeMemory() { return jvmFreeMemory; } public double getJvmTotalMemory() { return jvmTotalMemory; } public double getJvmMaxMemory() { return jvmMaxMemory; } public String getTomcatVersion() { return tomcatVersion; } public int getSessionCount() { return sessionCount; } public String getConfiguration() { return configuration; } public String getDbUrl() { return dbUrl; } public String getDbUser() { return dbUser; } public String getSolrUrl() { return solrUrl; } public String getFilestore() { return filestore; } public String getCmdLine() { return cmdLine; } }