view src/nabble/view/web/tools/Index.java @ 29:667e51ca939b

Disk Usage
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 03 Jul 2020 13:03:05 -0600
parents 22a701699b2a
children
line wrap: on
line source


package nabble.view.web.tools;

import fschmidt.util.java.IoUtils;
import fschmidt.util.servlet.ConnectionLimitFilter;
import nabble.model.Executors;
import nabble.model.ModelHome;
import nabble.model.ViewCount;
import nabble.model.export.Export;
import nabble.view.lib.UrlMappable;
import nabble.view.web.template.NabbleNamespace;
import nabble.view.web.user.OnlineStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;


public final class Index extends HttpServlet implements UrlMappable {

	private static final Logger logger = LoggerFactory.getLogger(Index.class);

	private static final DecimalFormat FORMATTER = new DecimalFormat("0.00");
	private static final Pattern URL_PATTERN = Pattern.compile("://[^/]+/tools/$");

	private static String path() {
		return "/tools/";
	}

	public Map<String,String[]> getParameterMapFromUrl(HttpServletRequest request,String mappedUrl) {
		return Collections.emptyMap();
	}

	public Pattern getUrlPattern() {
		return URL_PATTERN;
	}

	protected void service(HttpServletRequest request,HttpServletResponse response)
		throws ServletException, IOException
	{
		PrintWriter out = response.getWriter();
		float oneMega = 1024f * 1024f;
		float free = Runtime.getRuntime().freeMemory() / oneMega;
        float total = Runtime.getRuntime().totalMemory() / oneMega;
        float used = total - free;

		String loadAverage = null;
		try {
			Process process = Runtime.getRuntime().exec("uptime");
			InputStream input = process.getInputStream();
			byte[] result = IoUtils.readAll(input);
			input.close();
			loadAverage = new String(result).replaceAll(".*average:","");
		} catch(IOException e) {} // not on linux

		String diskUsage;
		{
			Process process = Runtime.getRuntime().exec(new String[]{"bash","-c","df -h | awk '{if ($0~\" /$\") {print $5}}'"});
			InputStream input = process.getInputStream();
			byte[] result = IoUtils.readAll(input);
			input.close();
			diskUsage = new String(result).trim();
		}

		Map<java.lang.Thread, java.lang.StackTraceElement[]> m = Thread.getAllStackTraces();
		int socketRead = 0;
		int idleThread = 0;
		int sleepingThread = 0;
		for (Map.Entry<Thread, StackTraceElement[]> entry : m.entrySet()) {
			StackTraceElement[] trace = entry.getValue();
			if (trace.length > 0) {
				String firstTrace = trace[0].toString();
				if (firstTrace.equals("java.net.SocketInputStream.socketRead0(Native Method)"))
					socketRead++;
				else if (firstTrace.equals("java.lang.Thread.sleep(Native Method)"))
					sleepingThread++;
				else if (firstTrace.equals("java.lang.Object.wait(Native Method)"))
					idleThread++;
			}
		}

		long viewCountDiffMillis = System.currentTimeMillis() - ViewCount.lastSaved;
		float minutesSinceLastSaved = viewCountDiffMillis / 60000f;

		long digestDiffMillis = System.currentTimeMillis() - ModelHome.lastDigestRun;
		float hoursSinceLastDigestRun = digestDiffMillis / 3600000f;
		
		out.print( "\r\n<html>\r\n	<head>\r\n		<title>Nabble tools</title>\r\n		<style type=\"text/css\">\r\n			.gray {\r\n				background-color: #eeeeee;\r\n				padding: .5em;\r\n			}\r\n			p { padding-left: .5em; }\r\n			td.row-label {\r\n				font-weight:bold;\r\n				padding: .1em .4em .1em 0;\r\n			}\r\n			td.row-separator { padding-top: 1em; }\r\n\r\n			td.category {\r\n				font-variant:small-caps;\r\n				text-align:center;\r\n				padding: 0 .5em;\r\n			}\r\n		</style>\r\n		<script type=\"text/javascript\">\r\n			var months = [\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"];\r\n			function fmt(i) { return i <= 9? \"0\" + i : i; };\r\n			function formatTime(date) {\r\n				var hours = date.getHours();\r\n				if( hours < 12 ) {\r\n					var xm = \"am\";\r\n					if (hours==0)\r\n						hours = 12;\r\n				} else {\r\n					var xm = \"pm\";\r\n					if (hours > 12)\r\n						hours -= 12;\r\n				}\r\n				return fmt(hours) + \":\" + fmt(date.getMinutes()) + xm;\r\n			};\r\n			function formatDate(date) {\r\n				return months[date.getMonth()] + \" \" + fmt(date.getDate()) + \", \" + date.getFullYear();\r\n			};\r\n			function formatDateTime(date) {\r\n				return formatDate(date) + \"; \" + formatTime(date);\r\n			};\r\n		</script>\r\n	</head>\r\n	<body style=\"font: .8em Verdana, Serif;\">\r\n		<p class=\"gray\">\r\n			Built time =\r\n			<b>\r\n			<script type=\"text/javascript\">\r\n				document.write(formatDateTime(new Date(" );
		out.print( (new Date(ClassLoader.getSystemResource("nabble/view/web/Index.class").openConnection().getLastModified()).getTime()) );
		out.print( ")));\r\n			</script>\r\n			</b>\r\n		</p>\r\n\r\n		<table style=\"font-size: 1em;\">\r\n			<tr>\r\n				<td class=\"category\" style=\"background-color:#fafafa;\">General</td>\r\n				<td style=\"padding:.5em 0\">\r\n					<p><a href=\"Admin.jtp\">Caches</a></p>\r\n					<p><a href=\"shell.luan\">Shell</a> (<a href=\"ShellHelp.jtp\">\r\n						<small>help</small>\r\n					</a>)\r\n					</p>\r\n					<p><a href=\"run.luan\">Run Batch</a></p>\r\n					<p><a href=\"SendMail.jtp\">Send mail</a></p>\r\n				</td>\r\n			</tr>\r\n			<tr>\r\n				<td class=\"category\" style=\"background-color:#e0e0e0;\">Sites</td>\r\n				<td style=\"padding:.5em 0\">\r\n					<p><a href=\"AdminNotice.jtp\">Administrator Notice</a></p>\r\n				</td>\r\n			</tr>\r\n			<tr>\r\n				<td class=\"category\" style=\"background-color:#d9d9d9;\">Others</td>\r\n				<td style=\"padding:.5em 0\">\r\n					<p><a href=\"TestMacro.jtp\">Test Macro</a></p>\r\n					<p><a href=\"Profile.jtp\">Profiling</a></p>\r\n					<p><a href=\"/tools2\">Generic tools</a></p>\r\n					<p><a href=\"OnlineUsers.jtp\">Online Users</a></p>\r\n				</td>\r\n			</tr>\r\n		</table>\r\n\r\n		<div class=\"gray\" style=\"margin: 1em 0\">\r\n			<table style=\"font-size:100%\">\r\n				<tr>\r\n					<td class=\"row-label\">Free Memory</td>\r\n					<td>\r\n						" );
		out.print( (String.format("%.2f",free)) );
		out.print( " Mb\r\n					</td>\r\n				</tr>\r\n				<tr>\r\n					<td class=\"row-label\">Used Memory</td>\r\n					<td>" );
		out.print( (String.format("%.2f",used)) );
		out.print( " Mb</td>\r\n				</tr>\r\n				<tr>\r\n					<td class=\"row-label\">Total Memory</td>\r\n					<td>" );
		out.print( (String.format("%.2f",total)) );
		out.print( " Mb</td>\r\n				</tr>\r\n				" );
 if (loadAverage != null) { 
		out.print( "\r\n				<tr>\r\n					<td class=\"row-label\">Load Average</td>\r\n					<td>" );
		out.print( (loadAverage) );
		out.print( "</td>\r\n				</tr>\r\n				" );
 } 
		out.print( "\r\n				<tr>\r\n					<td class=\"row-label\">Disk Usage</td>\r\n					<td>" );
		out.print( (diskUsage) );
		out.print( "</td>\r\n				</tr>\r\n				<tr>\r\n					<td class=\"row-label row-separator\">Pool Active Count</td>\r\n					<td class=\"row-separator\">" );
		out.print( (Executors.foregroundExecutor.getActiveCount()) );
		out.print( " threads</td>\r\n				</tr>\r\n				<tr>\r\n					<td class=\"row-label\">Pool Size</td>\r\n					<td>" );
		out.print( (Executors.foregroundExecutor.getPoolSize()) );
		out.print( " threads</td>\r\n				</tr>\r\n				<tr>\r\n					<td class=\"row-label\">Connection Limit</td>\r\n					<td>" );
		out.print( (ConnectionLimitFilter.counter.get()) );
		out.print( "/" );
		out.print( (ConnectionLimitFilter.max) );
		out.print( " (" );
		out.print( (ConnectionLimitFilter.queue.size()) );
		out.print( ")</td>\r\n				</tr>\r\n				<tr>\r\n					<td class=\"row-label\">Queue</td>\r\n					<td>" );
		out.print( (Executors.foregroundExecutor.getQueueSize()) );
		out.print( " connections</td>\r\n				</tr>\r\n				<tr>\r\n					<td class=\"row-label row-separator\">Thread Count</td>\r\n					<td class=\"row-separator\">" );
		out.print( (m.size()) );
		out.print( " threads</td>\r\n				</tr>\r\n				<tr>\r\n					<td class=\"row-label\">Idle Threads</td>\r\n					<td>" );
		out.print( (idleThread) );
		out.print( " threads are idle</td>\r\n				</tr>\r\n				<tr>\r\n					<td class=\"row-label\">Database Threads</td>\r\n					<td>" );
		out.print( (socketRead) );
		out.print( " socket reading</td>\r\n				</tr>\r\n				<tr>\r\n					<td class=\"row-label\">Sleeping Threads</td>\r\n					<td>" );
		out.print( (sleepingThread) );
		out.print( " threads are sleeping</td>\r\n				</tr>\r\n				<tr>\r\n					<td class=\"row-label row-separator\">Exporting</td>\r\n					<td class=\"row-separator\">[" );
		out.print( (csv(Export.exportSiteIds)) );
		out.print( "]</td>\r\n				</tr>\r\n				<tr>\r\n					<td class=\"row-label\">Backups Running</td>\r\n					<td>[" );
		out.print( (csv(NabbleNamespace.sitesRunningBackup)) );
		out.print( "]</td>\r\n				</tr>\r\n				<tr>\r\n					<td class=\"row-label\">Online users</td>\r\n					<td>" );
		out.print( (OnlineStatus.getOnlineStats()) );
		out.print( "</td>\r\n				</tr>\r\n				<tr>\r\n					<td class=\"row-label\">Views Last Saved</td>\r\n					<td style=\"color:#" );
		out.print( (minutesSinceLastSaved > 2f? "red":"black") );
		out.print( "\">" );
		out.print( (FORMATTER.format(minutesSinceLastSaved)) );
		out.print( " minutes ago</td>\r\n				</tr>\r\n				<tr>\r\n					<td class=\"row-label\">Last Digest Run</td>\r\n					<td style=\"color:#" );
		out.print( (hoursSinceLastDigestRun > 24f? "red":"black") );
		out.print( "\">" );
		out.print( (FORMATTER.format(hoursSinceLastDigestRun)) );
		out.print( " hours ago</td>\r\n				</tr>\r\n			</table>\r\n		</div>\r\n	</body>\r\n</html>\r\n" );

	}

	private String csv(Set<Long> ids) {
		Long[] idArray = ids.toArray(new Long[0]);
		StringBuilder buf = new StringBuilder();
		for (long id : idArray) {
			if (buf.length() > 0)
				buf.append(", ");
			buf.append(id);
		}
		return buf.toString();
	}
}