view src/nabble/view/web/tools/Index.jtp @ 27:22a701699b2a

add Disk.jtp
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 02 Jul 2020 16:00:09 -0600
parents 7ecd1a4ef557
children 667e51ca939b
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

		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;
		%>
		<html>
			<head>
				<title>Nabble tools</title>
				<style type="text/css">
					.gray {
						background-color: #eeeeee;
						padding: .5em;
					}
					p { padding-left: .5em; }
					td.row-label {
						font-weight:bold;
						padding: .1em .4em .1em 0;
					}
					td.row-separator { padding-top: 1em; }

					td.category {
						font-variant:small-caps;
						text-align:center;
						padding: 0 .5em;
					}
				</style>
				<script type="text/javascript">
					var months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
					function fmt(i) { return i <= 9? "0" + i : i; };
					function formatTime(date) {
						var hours = date.getHours();
						if( hours < 12 ) {
							var xm = "am";
							if (hours==0)
								hours = 12;
						} else {
							var xm = "pm";
							if (hours > 12)
								hours -= 12;
						}
						return fmt(hours) + ":" + fmt(date.getMinutes()) + xm;
					};
					function formatDate(date) {
						return months[date.getMonth()] + " " + fmt(date.getDate()) + ", " + date.getFullYear();
					};
					function formatDateTime(date) {
						return formatDate(date) + "; " + formatTime(date);
					};
				</script>
			</head>
			<body style="font: .8em Verdana, Serif;">
				<p class="gray">
					Built time =
					<b>
					<script type="text/javascript">
						document.write(formatDateTime(new Date(<%=new Date(ClassLoader.getSystemResource("nabble/view/web/Index.class").openConnection().getLastModified()).getTime()%>)));
					</script>
					</b>
				</p>

				<table style="font-size: 1em;">
					<tr>
						<td class="category" style="background-color:#fafafa;">General</td>
						<td style="padding:.5em 0">
							<p><a href="Admin.jtp">Caches</a></p>
							<p><a href="shell.luan">Shell</a> (<a href="ShellHelp.jtp">
								<small>help</small>
							</a>)
							</p>
							<p><a href="run.luan">Run Batch</a></p>
							<p><a href="SendMail.jtp">Send mail</a></p>
							<p><a href="Disk.jtp">Disks</a></p>
						</td>
					</tr>
					<tr>
						<td class="category" style="background-color:#e0e0e0;">Sites</td>
						<td style="padding:.5em 0">
							<p><a href="AdminNotice.jtp">Administrator Notice</a></p>
						</td>
					</tr>
					<tr>
						<td class="category" style="background-color:#d9d9d9;">Others</td>
						<td style="padding:.5em 0">
							<p><a href="TestMacro.jtp">Test Macro</a></p>
							<p><a href="Profile.jtp">Profiling</a></p>
							<p><a href="/tools2">Generic tools</a></p>
							<p><a href="OnlineUsers.jtp">Online Users</a></p>
						</td>
					</tr>
				</table>

				<div class="gray" style="margin: 1em 0">
					<table style="font-size:100%">
						<tr>
							<td class="row-label">Free Memory</td>
							<td>
								<%=String.format("%.2f",free)%> Mb
							</td>
						</tr>
						<tr>
							<td class="row-label">Used Memory</td>
							<td><%=String.format("%.2f",used)%> Mb</td>
						</tr>
						<tr>
							<td class="row-label">Total Memory</td>
							<td><%=String.format("%.2f",total)%> Mb</td>
						</tr>
						<% if (loadAverage != null) { %>
						<tr>
							<td class="row-label">Load Average</td>
							<td><%=loadAverage%></td>
						</tr>
						<% } %>
						<tr>
							<td class="row-label row-separator">Pool Active Count</td>
							<td class="row-separator"><%=Executors.foregroundExecutor.getActiveCount()%> threads</td>
						</tr>
						<tr>
							<td class="row-label">Pool Size</td>
							<td><%=Executors.foregroundExecutor.getPoolSize()%> threads</td>
						</tr>
						<tr>
							<td class="row-label">Connection Limit</td>
							<td><%=ConnectionLimitFilter.counter.get()%>/<%=ConnectionLimitFilter.max%> (<%=ConnectionLimitFilter.queue.size()%>)</td>
						</tr>
						<tr>
							<td class="row-label">Queue</td>
							<td><%=Executors.foregroundExecutor.getQueueSize()%> connections</td>
						</tr>
						<tr>
							<td class="row-label row-separator">Thread Count</td>
							<td class="row-separator"><%=m.size()%> threads</td>
						</tr>
						<tr>
							<td class="row-label">Idle Threads</td>
							<td><%=idleThread%> threads are idle</td>
						</tr>
						<tr>
							<td class="row-label">Database Threads</td>
							<td><%=socketRead%> socket reading</td>
						</tr>
						<tr>
							<td class="row-label">Sleeping Threads</td>
							<td><%=sleepingThread%> threads are sleeping</td>
						</tr>
						<tr>
							<td class="row-label row-separator">Exporting</td>
							<td class="row-separator">[<%=csv(Export.exportSiteIds)%>]</td>
						</tr>
						<tr>
							<td class="row-label">Backups Running</td>
							<td>[<%=csv(NabbleNamespace.sitesRunningBackup)%>]</td>
						</tr>
						<tr>
							<td class="row-label">Online users</td>
							<td><%=OnlineStatus.getOnlineStats()%></td>
						</tr>
						<tr>
							<td class="row-label">Views Last Saved</td>
							<td style="color:#<%=minutesSinceLastSaved > 2f? "red":"black"%>"><%=FORMATTER.format(minutesSinceLastSaved)%> minutes ago</td>
						</tr>
						<tr>
							<td class="row-label">Last Digest Run</td>
							<td style="color:#<%=hoursSinceLastDigestRun > 24f? "red":"black"%>"><%=FORMATTER.format(hoursSinceLastDigestRun)%> hours ago</td>
						</tr>
					</table>
				</div>
			</body>
		</html>
		<%
	}

	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();
	}
}
%>