1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.servlet;
20
21 import java.io.IOException;
22 import java.io.PrintWriter;
23 import java.lang.management.ManagementFactory;
24 import java.lang.management.MemoryMXBean;
25
26 import javax.servlet.ServletContext;
27 import javax.servlet.ServletException;
28 import javax.servlet.http.HttpServlet;
29 import javax.servlet.http.HttpServletRequest;
30 import javax.servlet.http.HttpServletResponse;
31
32 import org.eclipse.jetty.server.AbstractConnector;
33 import org.eclipse.jetty.server.Connector;
34 import org.eclipse.jetty.server.ConnectorStatistics;
35 import org.eclipse.jetty.server.Handler;
36 import org.eclipse.jetty.server.Server;
37 import org.eclipse.jetty.server.handler.ContextHandler;
38 import org.eclipse.jetty.server.handler.StatisticsHandler;
39 import org.eclipse.jetty.util.log.Log;
40 import org.eclipse.jetty.util.log.Logger;
41
42
43
44
45
46
47 public class StatisticsServlet extends HttpServlet
48 {
49 private static final Logger LOG = Log.getLogger(StatisticsServlet.class);
50
51 boolean _restrictToLocalhost = true;
52 private StatisticsHandler _statsHandler;
53 private MemoryMXBean _memoryBean;
54 private Connector[] _connectors;
55
56
57
58
59
60
61 public void init() throws ServletException
62 {
63 ServletContext context = getServletContext();
64 ContextHandler.Context scontext = (ContextHandler.Context) context;
65 Server _server = scontext.getContextHandler().getServer();
66
67 Handler handler = _server.getChildHandlerByClass(StatisticsHandler.class);
68
69 if (handler != null)
70 {
71 _statsHandler = (StatisticsHandler) handler;
72 }
73 else
74 {
75 LOG.warn("Statistics Handler not installed!");
76 return;
77 }
78
79 _memoryBean = ManagementFactory.getMemoryMXBean();
80 _connectors = _server.getConnectors();
81
82 if (getInitParameter("restrictToLocalhost") != null)
83 {
84 _restrictToLocalhost = "true".equals(getInitParameter("restrictToLocalhost"));
85 }
86 }
87
88
89
90
91
92
93 public void doPost(HttpServletRequest sreq, HttpServletResponse sres) throws ServletException, IOException
94 {
95 doGet(sreq, sres);
96 }
97
98
99
100
101
102
103 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
104 {
105 if (_statsHandler == null)
106 {
107 LOG.warn("Statistics Handler not installed!");
108 resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
109 return;
110 }
111 if (_restrictToLocalhost)
112 {
113 if (!"127.0.0.1".equals(req.getRemoteAddr()))
114 {
115 resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
116 return;
117 }
118 }
119
120 String wantXml = req.getParameter("xml");
121 if (wantXml == null)
122 wantXml = req.getParameter("XML");
123
124 if (wantXml != null && "true".equalsIgnoreCase(wantXml))
125 {
126 sendXmlResponse(resp);
127 }
128 else
129 {
130 sendTextResponse(resp);
131 }
132
133 }
134
135
136
137
138
139
140
141 private void sendXmlResponse(HttpServletResponse response) throws IOException
142 {
143 StringBuilder sb = new StringBuilder();
144
145 sb.append("<statistics>\n");
146
147 sb.append(" <requests>\n");
148 sb.append(" <statsOnMs>").append(_statsHandler.getStatsOnMs()).append("</statsOnMs>\n");
149
150 sb.append(" <requests>").append(_statsHandler.getRequests()).append("</requests>\n");
151 sb.append(" <requestsActive>").append(_statsHandler.getRequestsActive()).append("</requestsActive>\n");
152 sb.append(" <requestsActiveMax>").append(_statsHandler.getRequestsActiveMax()).append("</requestsActiveMax>\n");
153 sb.append(" <requestsTimeTotal>").append(_statsHandler.getRequestTimeTotal()).append("</requestsTimeTotal>\n");
154 sb.append(" <requestsTimeMean>").append(_statsHandler.getRequestTimeMean()).append("</requestsTimeMean>\n");
155 sb.append(" <requestsTimeMax>").append(_statsHandler.getRequestTimeMax()).append("</requestsTimeMax>\n");
156 sb.append(" <requestsTimeStdDev>").append(_statsHandler.getRequestTimeStdDev()).append("</requestsTimeStdDev>\n");
157
158 sb.append(" <dispatched>").append(_statsHandler.getDispatched()).append("</dispatched>\n");
159 sb.append(" <dispatchedActive>").append(_statsHandler.getDispatchedActive()).append("</dispatchedActive>\n");
160 sb.append(" <dispatchedActiveMax>").append(_statsHandler.getDispatchedActiveMax()).append("</dispatchedActiveMax>\n");
161 sb.append(" <dispatchedTimeTotalMs>").append(_statsHandler.getDispatchedTimeTotal()).append("</dispatchedTimeTotalMs>\n");
162 sb.append(" <dispatchedTimeMeanMs>").append(_statsHandler.getDispatchedTimeMean()).append("</dispatchedTimeMeanMs>\n");
163 sb.append(" <dispatchedTimeMaxMs>").append(_statsHandler.getDispatchedTimeMax()).append("</dispatchedTimeMaxMs>\n");
164 sb.append(" <dispatchedTimeStdDevMs>").append(_statsHandler.getDispatchedTimeStdDev()).append("</dispatchedTimeStdDevMs>\n");
165
166 sb.append(" <asyncRequests>").append(_statsHandler.getAsyncRequests()).append("</asyncRequests>\n");
167 sb.append(" <requestsSuspended>").append(_statsHandler.getAsyncRequestsWaiting()).append("</requestsSuspended>\n");
168 sb.append(" <requestsSuspendedMax>").append(_statsHandler.getAsyncRequestsWaitingMax()).append("</requestsSuspendedMax>\n");
169 sb.append(" <requestsResumed>").append(_statsHandler.getAsyncDispatches()).append("</requestsResumed>\n");
170 sb.append(" <requestsExpired>").append(_statsHandler.getExpires()).append("</requestsExpired>\n");
171 sb.append(" </requests>\n");
172
173 sb.append(" <responses>\n");
174 sb.append(" <responses1xx>").append(_statsHandler.getResponses1xx()).append("</responses1xx>\n");
175 sb.append(" <responses2xx>").append(_statsHandler.getResponses2xx()).append("</responses2xx>\n");
176 sb.append(" <responses3xx>").append(_statsHandler.getResponses3xx()).append("</responses3xx>\n");
177 sb.append(" <responses4xx>").append(_statsHandler.getResponses4xx()).append("</responses4xx>\n");
178 sb.append(" <responses5xx>").append(_statsHandler.getResponses5xx()).append("</responses5xx>\n");
179 sb.append(" <responsesBytesTotal>").append(_statsHandler.getResponsesBytesTotal()).append("</responsesBytesTotal>\n");
180 sb.append(" </responses>\n");
181
182 sb.append(" <connections>\n");
183 for (Connector connector : _connectors)
184 {
185 sb.append(" <connector>\n");
186 sb.append(" <name>").append(connector.getClass().getName()).append("@").append(connector.hashCode()).append("</name>\n");
187 sb.append(" <protocols>\n");
188 for (String protocol:connector.getProtocols())
189 sb.append(" <protocol>").append(protocol).append("</protocol>\n");
190 sb.append(" </protocols>\n");
191
192 ConnectorStatistics connectorStats = null;
193
194 if (connector instanceof AbstractConnector)
195 connectorStats = ((AbstractConnector)connector).getBean(ConnectorStatistics.class);
196 if (connectorStats == null)
197 sb.append(" <statsOn>false</statsOn>\n");
198 else
199 {
200 sb.append(" <statsOn>true</statsOn>\n");
201 sb.append(" <connections>").append(connectorStats.getConnections()).append("</connections>\n");
202 sb.append(" <connectionsOpen>").append(connectorStats.getConnectionsOpen()).append("</connectionsOpen>\n");
203 sb.append(" <connectionsOpenMax>").append(connectorStats.getConnectionsOpenMax()).append("</connectionsOpenMax>\n");
204 sb.append(" <connectionsDurationTotal>").append(connectorStats.getConnectionsDurationTotal()).append("</connectionsDurationTotal>\n");
205 sb.append(" <connectionsDurationMean>").append(connectorStats.getConnectionsDurationMean()).append("</connectionsDurationMean>\n");
206 sb.append(" <connectionsDurationMax>").append(connectorStats.getConnectionsDurationMax()).append("</connectionsDurationMax>\n");
207 sb.append(" <connectionsDurationStdDev>").append(connectorStats.getConnectionsDurationStdDev()).append("</connectionsDurationStdDev>\n");
208 sb.append(" <messagesIn>").append(connectorStats.getMessagesIn()).append("</messagesIn>\n");
209 sb.append(" <messagesOut>").append(connectorStats.getMessagesIn()).append("</messagesOut>\n");
210 sb.append(" <elapsedMs>").append(connectorStats.getStartedMillis()).append("</elapsedMs>\n");
211 }
212 sb.append(" </connector>\n");
213 }
214 sb.append(" </connections>\n");
215
216 sb.append(" <memory>\n");
217 sb.append(" <heapMemoryUsage>").append(_memoryBean.getHeapMemoryUsage().getUsed()).append("</heapMemoryUsage>\n");
218 sb.append(" <nonHeapMemoryUsage>").append(_memoryBean.getNonHeapMemoryUsage().getUsed()).append("</nonHeapMemoryUsage>\n");
219 sb.append(" </memory>\n");
220
221 sb.append("</statistics>\n");
222
223 response.setContentType("text/xml");
224 PrintWriter pout = response.getWriter();
225 pout.write(sb.toString());
226 }
227
228
229
230
231
232
233
234 private void sendTextResponse(HttpServletResponse response) throws IOException
235 {
236 StringBuilder sb = new StringBuilder();
237 sb.append(_statsHandler.toStatsHTML());
238
239 sb.append("<h2>Connections:</h2>\n");
240 for (Connector connector : _connectors)
241 {
242 sb.append("<h3>").append(connector.getClass().getName()).append("@").append(connector.hashCode()).append("</h3>");
243 sb.append("Protocols:");
244 for (String protocol:connector.getProtocols())
245 sb.append(protocol).append(" ");
246 sb.append(" <br />\n");
247
248 ConnectorStatistics connectorStats = null;
249
250 if (connector instanceof AbstractConnector)
251 connectorStats = ((AbstractConnector)connector).getBean(ConnectorStatistics.class);
252
253 if (connectorStats != null)
254 {
255 sb.append("Statistics gathering started ").append(connectorStats.getStartedMillis()).append("ms ago").append("<br />\n");
256 sb.append("Total connections: ").append(connectorStats.getConnections()).append("<br />\n");
257 sb.append("Current connections open: ").append(connectorStats.getConnectionsOpen()).append("<br />\n");;
258 sb.append("Max concurrent connections open: ").append(connectorStats.getConnectionsOpenMax()).append("<br />\n");
259 sb.append("Total connections duration: ").append(connectorStats.getConnectionsDurationTotal()).append("<br />\n");
260 sb.append("Mean connection duration: ").append(connectorStats.getConnectionsDurationMean()).append("<br />\n");
261 sb.append("Max connection duration: ").append(connectorStats.getConnectionsDurationMax()).append("<br />\n");
262 sb.append("Connection duration standard deviation: ").append(connectorStats.getConnectionsDurationStdDev()).append("<br />\n");
263 sb.append("Total messages in: ").append(connectorStats.getMessagesIn()).append("<br />\n");
264 sb.append("Total messages out: ").append(connectorStats.getMessagesOut()).append("<br />\n");
265 }
266 else
267 {
268 sb.append("Statistics gathering off.\n");
269 }
270
271 }
272
273 sb.append("<h2>Memory:</h2>\n");
274 sb.append("Heap memory usage: ").append(_memoryBean.getHeapMemoryUsage().getUsed()).append(" bytes").append("<br />\n");
275 sb.append("Non-heap memory usage: ").append(_memoryBean.getNonHeapMemoryUsage().getUsed()).append(" bytes").append("<br />\n");
276
277 response.setContentType("text/html");
278 PrintWriter pout = response.getWriter();
279 pout.write(sb.toString());
280
281 }
282 }