package com.agilecontrol.nea.core.web.shell; import argparser.ArgParser; import argparser.BooleanHolder; import com.agilecontrol.config.ResourcesConstant; import com.agilecontrol.nea.core.control.web.ServletContextManager; import com.agilecontrol.nea.core.control.web.WebUtils; import com.agilecontrol.nea.core.query.QueryEngine; import com.agilecontrol.nea.core.query.QueryUtils; import com.agilecontrol.nea.core.redis.JedisDatasource; import com.agilecontrol.nea.core.report.ReportUtils; import com.agilecontrol.nea.core.util.ConfigValues; import com.agilecontrol.nea.core.velocity.StringUtil; import com.agilecontrol.nea.core.web.shell.AbstractShellCmd; import com.agilecontrol.nea.core.web.shell.Shell; import com.agilecontrol.nea.util.Tools; import com.agilecontrol.nea.util.Validator; import java.io.File; import java.io.InputStream; import java.lang.reflect.Method; import java.net.InetAddress; import java.net.URL; import java.net.URLEncoder; import java.net.UnknownHostException; import java.sql.Connection; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Properties; import java.util.Set; import java.util.TreeSet; import javax.servlet.http.HttpServletRequest; import org.json.JSONObject; import org.springframework.core.env.Environment; @Shell( alias = "stat", admin = true, help = "stat [-all] [-thread] [-mem] 【-env】查看服务器信息" ) public class ServerInfo extends AbstractShellCmd { private String gitCommitTime; private String gitBranch; private static final Integer ZERO = new Integer(0); private String hostName; private String hostAddress; private Object threadMXBean; private Method getMemoryPoolMXBeans; private Method getName; private Method getType; private Method getUsage; private Method getPeakUsage; private Method getInit; private Method getUsed; private Method getCommitted; private Method getMax; private Method getThreadInfo; private Method getAllThreadIds; private Method getThreadCpuTime; private Method getThreadName; private Method getThreadState; private Method getLockName; private Method getStackTrace; private Method getThreadId; protected JSONObject process(String args, JSONObject envObj) throws Exception { JSONObject jo = new JSONObject(); jo.put("code", 0); String[] arg = args.split(" "); BooleanHolder allHolder = new BooleanHolder(); BooleanHolder threadHolder = new BooleanHolder(); BooleanHolder memHolder = new BooleanHolder(); BooleanHolder envHolder = new BooleanHolder(); ArgParser parser = new ArgParser(""); parser.addOption("-all %v #all", allHolder); parser.addOption("-thread %v #thread", threadHolder); parser.addOption("-mem %v #memory", memHolder); parser.addOption("-env %v #environment props", envHolder); parser.matchAllArgs(arg, 0, 0); this.preRegister(); StringBuilder sb = new StringBuilder(); sb.append("Server Information   at "); sb.append(((SimpleDateFormat)QueryUtils.dateTimeSecondsFormatter.get()).format(new Date())); String svrPath; if(allHolder.value || !threadHolder.value && !memHolder.value) { sb.append("
"); this.setProperty("Dir", ConfigValues.DIR_NEA_ROOT, sb); ServerInfo.Schema request = this.findDBSchema(); if(request != null) { this.setProperty("DB", request.dbLink, sb); this.setProperty("Schema", request.userName, sb); } ServletContextManager ru = (ServletContextManager)WebUtils.getServletContext().getAttribute("nea.web.svletctxmgr"); JedisDatasource name = (JedisDatasource)ru.getActor("nea.web.jedisds"); this.setProperty("Redis", name.getHost() + ":" + name.getPort() + ":db" + name.getDatabase(), sb); this.setProperty("server.id", ConfigValues.get("server.id"), sb); this.setProperty("JVMMaxMemory", this.readableSize(this.getMaxMemory().longValue()), sb); this.setProperty("JVMTotalMemory", this.readableSize(this.getTotalMemory().longValue()), sb); this.setProperty("JVMFreeMemory", this.readableSize(this.getFreeMemory().longValue()), sb); this.setProperty("AvailableProcessors", String.valueOf(this.getAvailableProcessors()), sb); this.setProperty("ActiveThreadCount", String.valueOf(this.getActiveThreadCount()), sb); this.setProperty("OSVersion", this.getOSVersion(), sb); this.setProperty("OSArch", this.getOSArch(), sb); this.setProperty("OSName", this.getOSName(), sb); this.setProperty("HostAddress", this.getHostAddress(), sb); this.setProperty("HostName", this.getHostName(), sb); this.setProperty("JavaVendor", this.getJavaVendor(), sb); this.setProperty("JavaVersion", this.getJavaVersion(), sb); this.setGitProperties(sb); svrPath = this.getServerLogPath(); if(svrPath != null && (new File(svrPath)).exists()) { HttpServletRequest passPath = (HttpServletRequest)envObj.get("request"); this.setProperty("ServerLog", "Download", sb); } sb.append("
"); } if(allHolder.value || envHolder.value) { sb.append("
"); this.listEnv(sb); } if(allHolder.value || threadHolder.value) { sb.append("
"); sb.append(this.listThreadDump()); } if(memHolder.value || allHolder.value) { sb.append("
"); sb.append(this.listMemoryPools(true)); } if(!allHolder.value && !threadHolder.value && !memHolder.value) { jo.put("message", sb.toString()); } else { sb.insert(0, "Server Infor"); sb.append(""); HttpServletRequest request1 = (HttpServletRequest)envObj.get("request"); ReportUtils ru1 = new ReportUtils(request1); String name1 = ru1.getUserName(); svrPath = ru1.getExportRootPath() + File.separator + ru1.getUser().getClientDomain() + File.separator + ru1.getUser().getUserId(); (new StringBuilder()).append(ru1.getOracleExportRootPath()).append(File.separator).append(ru1.getUser().getClientDomain()).append(File.separator).append(ru1.getUser().getUserId()).toString(); SimpleDateFormat sdf = new SimpleDateFormat("MMddHHmm"); String fileName = "svr" + sdf.format(new Date()) + ".html"; String filePath = svrPath + File.separator + fileName; new File(filePath); File svrDir = new File(svrPath); if(!svrDir.isDirectory()) { svrDir.mkdirs(); } Tools.writeFile(filePath, sb.toString(), "UTF-8"); jo.put("fileurl", WebUtils.getServletContext().getContextPath() + "/servlets/binserv/GetFile?filename=" + fileName); jo.put("target", "_blank"); } jo.put("gitCommitTime", this.gitCommitTime); jo.put("gitBranch", this.gitBranch); jo.put("script", "pc.stat()"); return jo; } private void setGitProperties(StringBuilder sb) throws Exception { Properties props = new Properties(); InputStream stream = null; label111: { try { String names = "/" + ServerInfo.class.getName().replace('.', '/') + ".class"; URL url = ServerInfo.class.getResource(names); String gitPropURL = StringUtil.replace(url.toString(), names, "/git.properties"); url = new URL(gitPropURL); stream = url.openStream(); if(stream != null) { props.load(stream); break label111; } } catch (Throwable var12) { this.logger.error("Fail to read git.properties from jar file", var12); return; } finally { if(stream != null) { stream.close(); } } return; } String[] var14 = new String[]{"git.branch", "git.build.user.name", "git.build.host", "git.build.time", "git.commit.time", "git.commit.id.abbrev", "git.dirty"}; String[] var15 = var14; int var16 = var14.length; for(int var7 = 0; var7 < var16; ++var7) { String name = var15[var7]; String value = props.getProperty(name); if(Validator.isNotNull(value)) { this.setProperty(this.Beautify(name), value, sb); } } this.gitCommitTime = props.getProperty("git.commit.time"); this.gitBranch = props.getProperty("git.branch"); } private String Beautify(String name) { StringBuilder sb = new StringBuilder(); char[] chars = name.toCharArray(); sb.append(String.valueOf(chars[0]).toUpperCase()); for(int i = 1; i < chars.length; ++i) { if(chars[i] != 46 && chars[i] != 95) { sb.append(chars[i]); } else { if(i <= chars.length - 2) { sb.append(String.valueOf(chars[i + 1]).toUpperCase()); } ++i; } } return sb.toString(); } private String readableSize(long size) { if(size <= 0L) { return "0"; } else { String[] units = new String[]{"B", "kB", "MB", "GB", "TB"}; int digitGroups = (int)(Math.log10((double)size) / Math.log10(1024.0D)); return (new DecimalFormat("#,##0.#")).format((double)size / Math.pow(1024.0D, (double)digitGroups)) + " " + units[digitGroups]; } } private ServerInfo.Schema findDBSchema() throws Exception { Connection conn = QueryEngine.getInstance().getConnection(); Throwable var2 = null; ServerInfo.Schema oracleURLPrefix1; try { String dbLink = conn.getMetaData().getURL(); String userName = conn.getMetaData().getUserName(); ServerInfo.Schema schema = null; if(Validator.isNotNull(dbLink)) { schema = new ServerInfo.Schema(null); String oracleURLPrefix = "jdbc:oracle:thin:@//"; if(dbLink.startsWith(oracleURLPrefix)) { schema.dbLink = dbLink.substring(oracleURLPrefix.length()); } else { schema.dbLink = dbLink; } schema.userName = userName; } oracleURLPrefix1 = schema; } catch (Throwable var15) { var2 = var15; throw var15; } finally { if(conn != null) { if(var2 != null) { try { conn.close(); } catch (Throwable var14) { var2.addSuppressed(var14); } } else { conn.close(); } } } return oracleURLPrefix1; } private void setProperty(String name, String o, StringBuilder sb) { sb.append("").append(name).append("").append(o).append(""); } private void setProperty(String o, StringBuilder sb) { sb.append("").append(o).append(""); } private void listEnv(StringBuilder sb) { Environment env = ResourcesConstant.environment; String[] profiles = env.getActiveProfiles(); sb.append(""); String[] var4 = profiles; int var5 = profiles.length; for(int var6 = 0; var6 < var5; ++var6) { String profile = var4[var6]; this.setProperty(profile, sb); } sb.append("
"); } public void preRegister() throws Exception { try { ClassLoader e = Thread.currentThread().getContextClassLoader(); Class clazz = e.loadClass("java.lang.management.ManagementFactory"); Method method = clazz.getMethod("getThreadMXBean", (Class[])null); this.threadMXBean = method.invoke((Object)null, (Object[])null); this.getMemoryPoolMXBeans = clazz.getMethod("getMemoryPoolMXBeans", (Class[])null); clazz = e.loadClass("java.lang.management.MemoryPoolMXBean"); this.getName = clazz.getMethod("getName", (Class[])null); this.getType = clazz.getMethod("getType", (Class[])null); this.getUsage = clazz.getMethod("getUsage", (Class[])null); this.getPeakUsage = clazz.getMethod("getPeakUsage", (Class[])null); clazz = e.loadClass("java.lang.management.MemoryUsage"); this.getInit = clazz.getMethod("getInit", (Class[])null); this.getUsed = clazz.getMethod("getUsed", (Class[])null); this.getCommitted = clazz.getMethod("getCommitted", (Class[])null); this.getMax = clazz.getMethod("getMax", (Class[])null); clazz = e.loadClass("java.lang.management.ThreadMXBean"); this.getThreadInfo = clazz.getMethod("getThreadInfo", new Class[]{Long.TYPE, Integer.TYPE}); this.getAllThreadIds = clazz.getMethod("getAllThreadIds", (Class[])null); this.getThreadCpuTime = clazz.getMethod("getThreadCpuTime", new Class[]{Long.TYPE}); clazz = e.loadClass("java.lang.management.ThreadInfo"); this.getThreadName = clazz.getMethod("getThreadName", (Class[])null); this.getThreadState = clazz.getMethod("getThreadState", (Class[])null); this.getLockName = clazz.getMethod("getLockName", (Class[])null); this.getStackTrace = clazz.getMethod("getStackTrace", (Class[])null); clazz = Thread.class; this.getThreadId = clazz.getMethod("getId", (Class[])null); } catch (Exception var4) { this.logger.debug("Cannot access platform ThreadMXBean", var4); } } public void postRegister(Boolean registrationDone) { } public void preDeregister() throws Exception { } public void postDeregister() { } public String getJavaVersion() { return System.getProperty("java.version"); } public String getJavaVendor() { return System.getProperty("java.vendor"); } public String getJavaVMName() { return System.getProperty("java.vm.name"); } public String getJavaVMVersion() { return System.getProperty("java.vm.version"); } public String getJavaVMVendor() { return System.getProperty("java.vm.vendor"); } public String getOSName() { return System.getProperty("os.name"); } public String getOSVersion() { return System.getProperty("os.version"); } public String getOSArch() { return System.getProperty("os.arch"); } public Long getTotalMemory() { return new Long(Runtime.getRuntime().totalMemory()); } public Long getFreeMemory() { return new Long(Runtime.getRuntime().freeMemory()); } public Long getMaxMemory() { try { Runtime e = Runtime.getRuntime(); Method m = e.getClass().getMethod("maxMemory", new Class[0]); return (Long)m.invoke(e, new Object[0]); } catch (Exception var3) { this.logger.error("Operation failed", var3); return new Long(-1L); } } public Integer getAvailableProcessors() { try { Runtime e = Runtime.getRuntime(); Method m = e.getClass().getMethod("availableProcessors", new Class[0]); return (Integer)m.invoke(e, new Object[0]); } catch (Exception var3) { this.logger.error("Operation failed", var3); return new Integer(-1); } } public String getHostName() { if(this.hostName == null) { try { this.hostName = InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException var2) { this.logger.error("Error looking up local hostname", var2); this.hostName = ""; } } return this.hostName; } public String getHostAddress() { if(this.hostAddress == null) { try { this.hostAddress = InetAddress.getLocalHost().getHostAddress(); } catch (UnknownHostException var2) { this.logger.error("Error looking up local address", var2); this.hostAddress = ""; } } return this.hostAddress; } public String listMemoryPools(boolean fancy) { if(this.getMemoryPoolMXBeans != null) { StringBuilder sbuf = new StringBuilder(4196); try { List poolList = (List)this.getMemoryPoolMXBeans.invoke((Object)null, (Object[])null); sbuf.append("Total Memory Pools: ").append(poolList.size()); sbuf.append("
"); for(Iterator i = poolList.iterator(); i.hasNext(); sbuf.append("

")) { Object pool = i.next(); String name = (String)this.getName.invoke(pool, (Object[])null); Object type = this.getType.invoke(pool, (Object[])null); sbuf.append("Pool: ").append(name); sbuf.append(" (").append(type).append(")"); Object peakUsage = this.getPeakUsage.invoke(pool, (Object[])null); Object usage = this.getUsage.invoke(pool, (Object[])null); sbuf.append("
"); if(usage != null && peakUsage != null) { Long init = (Long)this.getInit.invoke(peakUsage, (Object[])null); Long used = (Long)this.getUsed.invoke(peakUsage, (Object[])null); Long committed = (Long)this.getCommitted.invoke(peakUsage, (Object[])null); Long max = (Long)this.getMax.invoke(peakUsage, (Object[])null); sbuf.append("Peak Usage : "); sbuf.append("init:").append(init); sbuf.append(", used:").append(used); sbuf.append(", committed:").append(committed); sbuf.append(", max:").append(max); sbuf.append("
"); init = (Long)this.getInit.invoke(usage, (Object[])null); used = (Long)this.getUsed.invoke(usage, (Object[])null); committed = (Long)this.getCommitted.invoke(usage, (Object[])null); max = (Long)this.getMax.invoke(usage, (Object[])null); sbuf.append("Current Usage : "); sbuf.append("init:").append(init); sbuf.append(", used:").append(used); sbuf.append(", committed:").append(committed); sbuf.append(", max:").append(max); if(fancy) { ServerInfo.TextGraphHelper.poolUsage(sbuf, used.longValue(), committed.longValue(), max.longValue()); } } else { sbuf.append("Memory pool NOT valid!"); } } sbuf.append("
"); } catch (Exception var14) { ; } return sbuf.toString(); } else { return "Memory pool information available only under a JDK5+ compatible JVM!"; } } public Integer getActiveThreadCount() { return new Integer(this.getRootThreadGroup().activeCount()); } public Integer getActiveThreadGroupCount() { return new Integer(this.getRootThreadGroup().activeGroupCount()); } public String listThreadDump() { ThreadGroup root = this.getRootThreadGroup(); ServerInfo.ThreadGroupCount count = new ServerInfo.ThreadGroupCount(null); String threadGroupInfo = this.getThreadGroupInfo(root, count); String threadDump = "Total Threads: " + count.threads + "
Total Thread Groups: " + count.groups + "
" + threadGroupInfo; return threadDump; } public String listThreadCpuUtilization() { Set threads = this.getThreadCpuUtilization(); if(threads == null) { return "Thread cpu utilization requires J2SE5+"; } else { long totalCPU = 0L; StringBuilder buffer = new StringBuilder(); buffer.append(""); ServerInfo.ThreadCPU thread; for(Iterator i = threads.iterator(); i.hasNext(); totalCPU += thread.cpuTime) { thread = (ServerInfo.ThreadCPU)i.next(); buffer.append(""); } buffer.append("
Thread NameCPU (milliseconds)
").append(thread.name).append(""); buffer.append(thread.cpuTime).append("
  
Total"); buffer.append(totalCPU).append("
"); return buffer.toString(); } } private Set getThreadCpuUtilization() { if(this.threadMXBean == null) { return null; } else { try { TreeSet e = new TreeSet(); long[] threads = (long[])((long[])this.getAllThreadIds.invoke(this.threadMXBean, (Object[])null)); for(int i = 0; i < threads.length; ++i) { Long id = new Long(threads[i]); Long cpuTime = (Long)this.getThreadCpuTime.invoke(this.threadMXBean, new Object[]{id}); Object threadInfo = this.getThreadInfo.invoke(this.threadMXBean, new Object[]{id, ZERO}); String name = (String)this.getThreadName.invoke(threadInfo, (Object[])null); e.add(new ServerInfo.ThreadCPU(name, cpuTime.longValue())); } return e; } catch (Exception var8) { this.logger.error("Error retrieving thread cpu utiliation", var8); return null; } } } private ThreadGroup getRootThreadGroup() { ThreadGroup group; for(group = Thread.currentThread().getThreadGroup(); group.getParent() != null; group = group.getParent()) { ; } return group; } private String getThreadGroupInfo(ThreadGroup group, ServerInfo.ThreadGroupCount count) { StringBuilder rc = new StringBuilder(); ++count.groups; rc.append("
"); rc.append("Thread Group: " + group.getName()); rc.append(" : "); rc.append("max priority:" + group.getMaxPriority() + ", demon:" + group.isDaemon()); rc.append("
"); Thread[] threads = new Thread[group.activeCount()]; group.enumerate(threads, false); for(int groups = 0; groups < threads.length && threads[groups] != null; ++groups) { ++count.threads; rc.append(""); rc.append("Thread: " + threads[groups].getName()); rc.append(" : "); rc.append("priority:" + threads[groups].getPriority() + ", demon:" + threads[groups].isDaemon()); this.outputJdk5ThreadMXBeanInfo(rc, threads[groups]); } ThreadGroup[] var7 = new ThreadGroup[group.activeGroupCount()]; group.enumerate(var7, false); for(int i = 0; i < var7.length && var7[i] != null; ++i) { rc.append(this.getThreadGroupInfo(var7[i], count)); } rc.append("
"); return rc.toString(); } private void outputJdk5ThreadMXBeanInfo(StringBuilder sbuf, Thread thread) { if(this.threadMXBean != null) { try { Long threadId = (Long)this.getThreadId.invoke(thread, (Object[])null); Object threadInfo = this.getThreadInfo.invoke(this.threadMXBean, new Object[]{threadId, new Integer(Integer.MAX_VALUE)}); Object threadState = this.getThreadState.invoke(threadInfo, (Object[])null); String threadLockName = (String)this.getLockName.invoke(threadInfo, (Object[])null); Object[] stackTrace = (Object[])((Object[])this.getStackTrace.invoke(threadInfo, (Object[])null)); sbuf.append(", threadId:").append(threadId); sbuf.append(", threadState:").append(threadState); sbuf.append(", threadLockName:").append(threadLockName); sbuf.append("
"); if(stackTrace.length > 0) { sbuf.append("
"); for(int i = 0; i < stackTrace.length; ++i) { sbuf.append(stackTrace[i]).append("
"); } sbuf.append("
"); } } catch (Exception var9) { ; } } else { sbuf.append("
"); } } public String displayPackageInfo(String pkgName) { Package pkg = Package.getPackage(pkgName); if(pkg == null) { return "

Package:" + pkgName + " Not Found!

"; } else { StringBuilder info = new StringBuilder("

Package: " + pkgName + "

"); this.displayPackageInfo(pkg, info); return info.toString(); } } private void displayPackageInfo(Package pkg, StringBuilder info) { info.append("
\n");
      info.append("SpecificationTitle: " + pkg.getSpecificationTitle());
      info.append("\nSpecificationVersion: " + pkg.getSpecificationVersion());
      info.append("\nSpecificationVendor: " + pkg.getSpecificationVendor());
      info.append("\nImplementationTitle: " + pkg.getImplementationTitle());
      info.append("\nImplementationVersion: " + pkg.getImplementationVersion());
      info.append("\nImplementationVendor: " + pkg.getImplementationVendor());
      info.append("\nisSealed: " + pkg.isSealed());
      info.append("
\n"); } private static class ThreadGroupCount { public int threads; public int groups; private ThreadGroupCount() { } // $FF: synthetic method ThreadGroupCount(Object x0) { this(); } } private static class ThreadCPU implements Comparable { public String name; public long cpuTime; public ThreadCPU(String name, long cpuTime) { this.name = name; this.cpuTime = cpuTime / 1000000L; } public int compareTo(Object o) { ServerInfo.ThreadCPU other = (ServerInfo.ThreadCPU)o; long value = this.cpuTime - other.cpuTime; return value > 0L?-1:(value < 0L?1:this.name.compareTo(other.name)); } } private static class TextGraphHelper { static final DecimalFormat formatter = new DecimalFormat("#.##"); static final long KILO = 1024L; static final long MEGA = 1048576L; static final long GIGA = 1073741824L; static final int factor = 70; static char[] fixedline; static char[] baseline; static char[] barline; static char[] spaces; public static void poolUsage(StringBuilder sbuf, long used, long committed, long max) { long assumedMax = max == -1L?committed:max; int localUsed = (int)(70L * used / assumedMax); int localCommitted = (int)(70L * committed / assumedMax); byte localMax = 70; sbuf.append("

"); sbuf.append(baseline, 0, localCommitted).append("| committed:").append(outputNumber(committed)).append("
"); sbuf.append(fixedline).append("
"); sbuf.append(barline, 0, localUsed); if(localUsed < localCommitted) { sbuf.append((char)(localUsed > 0?'/':'|')); sbuf.append(spaces, 0, localCommitted - localUsed - 1); } sbuf.append('|'); if(localCommitted < localMax) { sbuf.append(spaces, 0, localMax - localCommitted - 1); sbuf.append('|'); } sbuf.append(" max:").append(outputNumber(max)).append("
"); sbuf.append(fixedline).append("
"); sbuf.append(baseline, 0, localUsed).append("| used:").append(outputNumber(used)); sbuf.append("
"); } private static String outputNumber(long value) { return value >= 1073741824L?formatter.format((double)value / 1.073741824E9D) + "Gb":(value >= 1048576L?formatter.format((double)value / 1048576.0D) + "Mb":(value >= 1024L?formatter.format((double)value / 1024.0D) + "Kb":(value >= 0L?value + "b":Long.toString(value)))); } static { StringBuilder sbuf0 = new StringBuilder(); StringBuilder sbuf1 = new StringBuilder(); StringBuilder sbuf2 = new StringBuilder(); StringBuilder sbuf3 = new StringBuilder(); sbuf0.append('+'); sbuf1.append('|'); sbuf2.append('|'); for(int i = 1; i < 70; ++i) { sbuf0.append('-'); sbuf1.append('-'); sbuf2.append('/'); sbuf3.append(' '); } sbuf0.append('+'); fixedline = sbuf0.toString().toCharArray(); baseline = sbuf1.toString().toCharArray(); barline = sbuf2.toString().toCharArray(); spaces = sbuf3.toString().toCharArray(); } } private class Schema { String dbLink; String userName; private Schema() { } // $FF: synthetic method Schema(Object x1) { this(); } } }