1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.servlet;
15
16 import java.io.IOException;
17 import java.io.PrintWriter;
18 import java.lang.management.ManagementFactory;
19 import java.lang.management.MemoryMXBean;
20 import javax.servlet.ServletContext;
21 import javax.servlet.ServletException;
22 import javax.servlet.http.HttpServlet;
23 import javax.servlet.http.HttpServletRequest;
24 import javax.servlet.http.HttpServletResponse;
25
26 import org.eclipse.jetty.server.Connector;
27 import org.eclipse.jetty.server.Handler;
28 import org.eclipse.jetty.server.Server;
29 import org.eclipse.jetty.server.handler.ContextHandler;
30 import org.eclipse.jetty.server.handler.StatisticsHandler;
31 import org.eclipse.jetty.util.log.Log;
32
33 public class StatisticsServlet extends HttpServlet
34 {
35 boolean _restrictToLocalhost = true;
36 private StatisticsHandler _statsHandler;
37 private MemoryMXBean _memoryBean;
38 private Connector[] _connectors;
39
40 public void init() throws ServletException
41 {
42 ServletContext context = getServletContext();
43 ContextHandler.Context scontext = (ContextHandler.Context) context;
44 Server _server = scontext.getContextHandler().getServer();
45
46 Handler handler = _server.getChildHandlerByClass(StatisticsHandler.class);
47
48 if (handler != null)
49 {
50 _statsHandler = (StatisticsHandler) handler;
51 }
52 else
53 {
54 Log.warn("Statistics Handler not installed!");
55 return;
56 }
57
58 _memoryBean = ManagementFactory.getMemoryMXBean();
59 _connectors = _server.getConnectors();
60
61 if (getInitParameter("restrictToLocalhost") != null)
62 {
63 _restrictToLocalhost = "true".equals(getInitParameter("restrictToLocalhost"));
64 }
65
66 }
67
68 public void doPost(HttpServletRequest sreq, HttpServletResponse sres) throws ServletException, IOException
69 {
70 doGet(sreq, sres);
71 }
72
73 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
74 {
75 if (_statsHandler == null)
76 {
77 Log.warn("Statistics Handler not installed!");
78 resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
79 return;
80 }
81 if (_restrictToLocalhost)
82 {
83 if (!"127.0.0.1".equals(req.getRemoteAddr()))
84 {
85 resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
86 return;
87 }
88 }
89
90 String wantXml = req.getParameter("xml");
91 if (wantXml == null)
92 wantXml = req.getParameter("XML");
93
94 if (wantXml != null && "true".equalsIgnoreCase(wantXml))
95 {
96 sendXmlResponse(resp);
97 }
98 else
99 {
100 sendTextResponse(resp);
101 }
102
103 }
104
105 private void sendXmlResponse(HttpServletResponse response) throws IOException
106 {
107 StringBuilder sb = new StringBuilder();
108
109 sb.append("<statistics>\n");
110
111 sb.append(" <requests>\n");
112 sb.append(" <statsOnMs>").append(_statsHandler.getStatsOnMs()).append("</statsOnMs>\n");
113 sb.append(" <requests>").append(_statsHandler.getRequests()).append("</requests>\n");
114 sb.append(" <requestsExpired>").append(_statsHandler.getRequestsExpired()).append("</requestsExpired>\n");
115 sb.append(" <requestsResumed>").append(_statsHandler.getRequestsResumed()).append("</requestsResumed>\n");
116 sb.append(" <requestsActive>").append(_statsHandler.getRequestsActive()).append("</requestsActive>\n");
117 sb.append(" <requestsActiveMax>").append(_statsHandler.getRequestsActiveMax()).append("</requestsActiveMax>\n");
118 sb.append(" <requestsTimeTotal>").append(_statsHandler.getRequestTimeTotal()).append("</requestsTimeTotal>\n");
119 sb.append(" <requestsTimeAverage>").append(_statsHandler.getRequestTimeAverage()).append("</requestsTimeAverage>\n");
120 sb.append(" <requestsTimeMin>").append(_statsHandler.getRequestTimeMin()).append("</requestsTimeMin>\n");
121 sb.append(" <requestsTimeMax>").append(_statsHandler.getRequestTimeMax()).append("</requestsTimeMax>\n");
122 sb.append(" <suspendTimeMin>").append(_statsHandler.getSuspendedTimeMin()).append("</suspendTimeMin>\n");
123 sb.append(" <suspendTimeTotal>").append(_statsHandler.getSuspendedTimeTotal()).append("</suspendTimeTotal>\n");
124 sb.append(" </requests>\n");
125
126 sb.append(" <responses>\n");
127 sb.append(" <responses1xx>").append(_statsHandler.getResponses1xx()).append("</responses1xx>\n");
128 sb.append(" <responses2xx>").append(_statsHandler.getResponses2xx()).append("</responses2xx>\n");
129 sb.append(" <responses3xx>").append(_statsHandler.getResponses3xx()).append("</responses3xx>\n");
130 sb.append(" <responses4xx>").append(_statsHandler.getResponses4xx()).append("</responses4xx>\n");
131 sb.append(" <responses5xx>").append(_statsHandler.getResponses5xx()).append("</responses5xx>\n");
132 sb.append(" <responsesBytesTotal>").append(_statsHandler.getResponsesBytesTotal()).append("</responsesBytesTotal>\n");
133 sb.append(" </responses>\n");
134
135 sb.append(" <connections>\n");
136 for (Connector connector : _connectors)
137 {
138 sb.append(" <connector>\n");
139 sb.append(" <name>").append(connector.getName()).append("</name>\n");
140 sb.append(" <statsOn>").append(connector.getStatsOn()).append("</statsOn>\n");
141 if (connector.getStatsOn())
142 {
143 sb.append(" <statsOnMs>").append(connector.getStatsOnMs()).append("</statsOnMs>\n");
144 sb.append(" <connections>").append(connector.getConnections()).append("</connections>\n");
145 sb.append(" <connectionsOpen>").append(connector.getConnectionsOpen()).append("</connectionsOpen>\n");
146 sb.append(" <connectionsOpenMin>").append(connector.getConnectionsOpenMin()).append("</connectionsOpenMin>\n");
147 sb.append(" <connectionsOpenMax>").append(connector.getConnectionsOpenMax()).append("</connectionsOpenMax>\n");
148 sb.append(" <connectionsDurationTotal>").append(connector.getConnectionsDurationTotal()).append("</connectionsDurationTotal>\n");
149 sb.append(" <connectionsDurationAve>").append(connector.getConnectionsDurationAve()).append("</connectionsDurationAve>\n");
150 sb.append(" <connectionsDurationMin>").append(connector.getConnectionsDurationMin()).append("</connectionsDurationMin>\n");
151 sb.append(" <connectionsDurationMax>").append(connector.getConnectionsDurationMax()).append("</connectionsDurationMax>\n");
152 sb.append(" <requests>").append(connector.getRequests()).append("</requests>\n");
153 sb.append(" <connectionsRequestsAve>").append(connector.getConnectionsRequestsAve()).append("</connectionsRequestsAve>\n");
154 sb.append(" <connectionsRequestsMin>").append(connector.getConnectionsRequestsMin()).append("</connectionsRequestsMin>\n");
155 sb.append(" <connectionsRequestsMax>").append(connector.getConnectionsRequestsMax()).append("</connectionsRequestsMax>\n");
156 }
157 sb.append(" </connector>\n");
158 }
159 sb.append(" </connections>\n");
160
161 sb.append(" <memory>\n");
162 sb.append(" <heapMemoryUsage>").append(_memoryBean.getHeapMemoryUsage().getUsed()).append("</heapMemoryUsage>\n");
163 sb.append(" <nonHeapMemoryUsage>").append(_memoryBean.getNonHeapMemoryUsage().getUsed()).append("</nonHeapMemoryUsage>\n");
164 sb.append(" </memory>\n");
165
166 sb.append("</statistics>\n");
167
168 response.setContentType("text/xml");
169 PrintWriter pout = response.getWriter();
170 pout.write(sb.toString());
171 }
172
173 private void sendTextResponse(HttpServletResponse response) throws IOException
174 {
175
176 StringBuilder sb = new StringBuilder();
177
178 sb.append("<h1>Statistics:</h1>\n");
179
180 sb.append("<h2>Requests:</h2>\n");
181 sb.append("Statistics gathering started ").append(_statsHandler.getStatsOnMs()).append("ms ago").append("<br />\n");
182 sb.append("Total requests: ").append(_statsHandler.getRequests()).append("<br />\n");
183 sb.append("Total requests expired: ").append(_statsHandler.getRequestsExpired()).append("<br />\n");
184 sb.append("Total requests resumed: ").append(_statsHandler.getRequestsResumed()).append("<br />\n");
185 sb.append("Current requests active: ").append(_statsHandler.getRequestsActive()).append("<br />\n");
186 sb.append("Max concurrent requests active: ").append(_statsHandler.getRequestsActiveMax()).append("<br />\n");
187 sb.append("Total requests time: ").append(_statsHandler.getRequestTimeTotal()).append("<br />\n");
188 sb.append("Average request time: ").append(_statsHandler.getRequestTimeAverage()).append("<br />\n");
189 sb.append("Min request time: ").append(_statsHandler.getRequestTimeMin()).append("<br />\n");
190 sb.append("Max request time: ").append(_statsHandler.getRequestTimeMax()).append("<br />\n");
191 sb.append("Min suspended request time: ").append(_statsHandler.getSuspendedTimeMin()).append("<br />\n");
192 sb.append("Total suspended requests time: ").append(_statsHandler.getSuspendedTimeTotal()).append("<br />\n");
193
194 sb.append("<h2>Responses:</h2>\n");
195 sb.append("1xx responses: ").append(_statsHandler.getResponses1xx()).append("<br />\n");
196 sb.append("2xx responses: ").append(_statsHandler.getResponses2xx()).append("<br />\n");
197 sb.append("3xx responses: ").append(_statsHandler.getResponses3xx()).append("<br />\n");
198 sb.append("4xx responses: ").append(_statsHandler.getResponses4xx()).append("<br />\n");
199 sb.append("5xx responses: ").append(_statsHandler.getResponses5xx()).append("<br />\n");
200 sb.append("Bytes sent total: ").append(_statsHandler.getResponsesBytesTotal()).append("<br />\n");
201
202 sb.append("<h2>Connections:</h2>\n");
203 for (Connector connector : _connectors)
204 {
205 sb.append("<h3>").append(connector.getName()).append("</h3>");
206
207 if (connector.getStatsOn())
208 {
209 sb.append("Statistics gathering started ").append(connector.getStatsOnMs()).append("ms ago").append("<br />\n");
210 sb.append("Total connections: ").append(connector.getConnections()).append("<br />\n");
211 sb.append("Current connections open: ").append(connector.getConnectionsOpen());
212 sb.append("Min concurrent connections open: ").append(connector.getConnectionsOpenMin()).append("<br />\n");
213 sb.append("Max concurrent connections open: ").append(connector.getConnectionsOpenMax()).append("<br />\n");
214 sb.append("Total connections duration: ").append(connector.getConnectionsDurationTotal()).append("<br />\n");
215 sb.append("Average connection duration: ").append(connector.getConnectionsDurationAve()).append("<br />\n");
216 sb.append("Min connection duration: ").append(connector.getConnectionsDurationMin()).append("<br />\n");
217 sb.append("Max connection duration: ").append(connector.getConnectionsDurationMax()).append("<br />\n");
218 sb.append("Total requests: ").append(connector.getRequests()).append("<br />\n");
219 sb.append("Average requests per connection: ").append(connector.getConnectionsRequestsAve()).append("<br />\n");
220 sb.append("Min requests per connection: ").append(connector.getConnectionsRequestsMin()).append("<br />\n");
221 sb.append("Max requests per connection: ").append(connector.getConnectionsRequestsMax()).append("<br />\n");
222 }
223 else
224 {
225 sb.append("Statistics gathering off.\n");
226 }
227
228 }
229
230 sb.append("<h2>Memory:</h2>\n");
231 sb.append("Heap memory usage: ").append(_memoryBean.getHeapMemoryUsage().getUsed()).append(" bytes").append("<br />\n");
232 sb.append("Non-heap memory usage: ").append(_memoryBean.getNonHeapMemoryUsage().getUsed()).append(" bytes").append("<br />\n");
233
234 response.setContentType("text/html");
235 PrintWriter pout = response.getWriter();
236 pout.write(sb.toString());
237
238 }
239 }