View Javadoc

1   // ========================================================================
2   // Copyright (c) 2008-2009 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses.
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; // defaults to 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 }