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  
21  import javax.servlet.ServletContext;
22  import javax.servlet.ServletException;
23  import javax.servlet.http.HttpServlet;
24  import javax.servlet.http.HttpServletRequest;
25  import javax.servlet.http.HttpServletResponse;
26  
27  import org.eclipse.jetty.server.Connector;
28  import org.eclipse.jetty.server.Handler;
29  import org.eclipse.jetty.server.Server;
30  import org.eclipse.jetty.server.handler.ContextHandler;
31  import org.eclipse.jetty.server.handler.StatisticsHandler;
32  import org.eclipse.jetty.util.log.Log;
33  import org.eclipse.jetty.util.log.Logger;
34  
35  public class StatisticsServlet extends HttpServlet
36  {
37      private static final Logger LOG = Log.getLogger(StatisticsServlet.class);
38  
39      boolean _restrictToLocalhost = true; // defaults to true
40      private StatisticsHandler _statsHandler;
41      private MemoryMXBean _memoryBean;
42      private Connector[] _connectors;
43  
44      public void init() throws ServletException
45      {
46          ServletContext context = getServletContext();
47          ContextHandler.Context scontext = (ContextHandler.Context) context;
48          Server _server = scontext.getContextHandler().getServer();
49  
50          Handler handler = _server.getChildHandlerByClass(StatisticsHandler.class);
51  
52          if (handler != null)
53          {
54              _statsHandler = (StatisticsHandler) handler;
55          }
56          else
57          {
58              LOG.warn("Statistics Handler not installed!");
59              return;
60          }
61          
62          _memoryBean = ManagementFactory.getMemoryMXBean();
63          _connectors = _server.getConnectors();
64  
65          if (getInitParameter("restrictToLocalhost") != null)
66          {
67              _restrictToLocalhost = "true".equals(getInitParameter("restrictToLocalhost"));
68          }
69  
70      }
71  
72      public void doPost(HttpServletRequest sreq, HttpServletResponse sres) throws ServletException, IOException
73      {
74          doGet(sreq, sres);
75      }
76  
77      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
78      {
79          if (_statsHandler == null)
80          {
81              LOG.warn("Statistics Handler not installed!");
82              resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
83              return;
84          }
85          if (_restrictToLocalhost)
86          {
87              if (!"127.0.0.1".equals(req.getRemoteAddr()))
88              {
89                  resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
90                  return;
91              }
92          }
93  
94          String wantXml = req.getParameter("xml");
95          if (wantXml == null)
96            wantXml = req.getParameter("XML");
97  
98          if (wantXml != null && "true".equalsIgnoreCase(wantXml))
99          {
100             sendXmlResponse(resp);
101         }
102         else
103         {
104             sendTextResponse(resp);
105         }
106 
107     }
108 
109     private void sendXmlResponse(HttpServletResponse response) throws IOException
110     {
111         StringBuilder sb = new StringBuilder();
112 
113         sb.append("<statistics>\n");
114 
115         sb.append("  <requests>\n");
116         sb.append("    <statsOnMs>").append(_statsHandler.getStatsOnMs()).append("</statsOnMs>\n");
117         
118         sb.append("    <requests>").append(_statsHandler.getRequests()).append("</requests>\n");
119         sb.append("    <requestsActive>").append(_statsHandler.getRequestsActive()).append("</requestsActive>\n");
120         sb.append("    <requestsActiveMax>").append(_statsHandler.getRequestsActiveMax()).append("</requestsActiveMax>\n");
121         sb.append("    <requestsTimeTotal>").append(_statsHandler.getRequestTimeTotal()).append("</requestsTimeTotal>\n");
122         sb.append("    <requestsTimeMean>").append(_statsHandler.getRequestTimeMean()).append("</requestsTimeMean>\n");
123         sb.append("    <requestsTimeMax>").append(_statsHandler.getRequestTimeMax()).append("</requestsTimeMax>\n");
124         sb.append("    <requestsTimeStdDev>").append(_statsHandler.getRequestTimeStdDev()).append("</requestsTimeStdDev>\n");
125 
126         sb.append("    <dispatched>").append(_statsHandler.getDispatched()).append("</dispatched>\n");
127         sb.append("    <dispatchedActive>").append(_statsHandler.getDispatchedActive()).append("</dispatchedActive>\n");
128         sb.append("    <dispatchedActiveMax>").append(_statsHandler.getDispatchedActiveMax()).append("</dispatchedActiveMax>\n");
129         sb.append("    <dispatchedTimeTotal>").append(_statsHandler.getDispatchedTimeTotal()).append("</dispatchedTimeTotal>\n");
130         sb.append("    <dispatchedTimeMean").append(_statsHandler.getDispatchedTimeMean()).append("</dispatchedTimeMean>\n");
131         sb.append("    <dispatchedTimeMax>").append(_statsHandler.getDispatchedTimeMax()).append("</dispatchedTimeMax>\n");
132         sb.append("    <dispatchedTimeStdDev").append(_statsHandler.getDispatchedTimeStdDev()).append("</dispatchedTimeStdDev>\n");
133         
134         sb.append("    <requestsSuspended>").append(_statsHandler.getSuspends()).append("</requestsSuspended>\n");
135         sb.append("    <requestsExpired>").append(_statsHandler.getExpires()).append("</requestsExpired>\n");
136         sb.append("    <requestsResumed>").append(_statsHandler.getResumes()).append("</requestsResumed>\n");
137         sb.append("  </requests>\n");
138 
139         sb.append("  <responses>\n");
140         sb.append("    <responses1xx>").append(_statsHandler.getResponses1xx()).append("</responses1xx>\n");
141         sb.append("    <responses2xx>").append(_statsHandler.getResponses2xx()).append("</responses2xx>\n");
142         sb.append("    <responses3xx>").append(_statsHandler.getResponses3xx()).append("</responses3xx>\n");
143         sb.append("    <responses4xx>").append(_statsHandler.getResponses4xx()).append("</responses4xx>\n");
144         sb.append("    <responses5xx>").append(_statsHandler.getResponses5xx()).append("</responses5xx>\n");
145         sb.append("    <responsesBytesTotal>").append(_statsHandler.getResponsesBytesTotal()).append("</responsesBytesTotal>\n");
146         sb.append("  </responses>\n");
147 
148         sb.append("  <connections>\n");
149         for (Connector connector : _connectors)
150         {
151         	sb.append("    <connector>\n");
152         	sb.append("      <name>").append(connector.getName()).append("</name>\n");
153         	sb.append("      <statsOn>").append(connector.getStatsOn()).append("</statsOn>\n");
154             if (connector.getStatsOn())
155             {
156             	sb.append("    <statsOnMs>").append(connector.getStatsOnMs()).append("</statsOnMs>\n");
157             	sb.append("    <connections>").append(connector.getConnections()).append("</connections>\n");
158             	sb.append("    <connectionsOpen>").append(connector.getConnectionsOpen()).append("</connectionsOpen>\n");
159             	sb.append("    <connectionsOpenMax>").append(connector.getConnectionsOpenMax()).append("</connectionsOpenMax>\n");
160             	sb.append("    <connectionsDurationTotal>").append(connector.getConnectionsDurationTotal()).append("</connectionsDurationTotal>\n");
161             	sb.append("    <connectionsDurationMean>").append(connector.getConnectionsDurationMean()).append("</connectionsDurationMean>\n");
162             	sb.append("    <connectionsDurationMax>").append(connector.getConnectionsDurationMax()).append("</connectionsDurationMax>\n");
163                 sb.append("    <connectionsDurationStdDev>").append(connector.getConnectionsDurationStdDev()).append("</connectionsDurationStdDev>\n");
164                 sb.append("    <requests>").append(connector.getRequests()).append("</requests>\n");
165                 sb.append("    <connectionsRequestsMean>").append(connector.getConnectionsRequestsMean()).append("</connectionsRequestsMean>\n");
166                 sb.append("    <connectionsRequestsMax>").append(connector.getConnectionsRequestsMax()).append("</connectionsRequestsMax>\n");
167                 sb.append("    <connectionsRequestsStdDev>").append(connector.getConnectionsRequestsStdDev()).append("</connectionsRequestsStdDev>\n");
168             }
169             sb.append("    </connector>\n");
170         }
171         sb.append("  </connections>\n");
172 
173         sb.append("  <memory>\n");
174         sb.append("    <heapMemoryUsage>").append(_memoryBean.getHeapMemoryUsage().getUsed()).append("</heapMemoryUsage>\n");
175         sb.append("    <nonHeapMemoryUsage>").append(_memoryBean.getNonHeapMemoryUsage().getUsed()).append("</nonHeapMemoryUsage>\n");
176         sb.append("  </memory>\n");
177 
178         sb.append("</statistics>\n");
179 
180         response.setContentType("text/xml");
181         PrintWriter pout = response.getWriter();
182         pout.write(sb.toString());
183     }
184 
185     private void sendTextResponse(HttpServletResponse response) throws IOException
186     {
187         StringBuilder sb = new StringBuilder();
188         sb.append(_statsHandler.toStatsHTML());
189 
190         sb.append("<h2>Connections:</h2>\n");
191         for (Connector connector : _connectors)
192         {
193             sb.append("<h3>").append(connector.getName()).append("</h3>");
194 
195             if (connector.getStatsOn())
196             {
197                 sb.append("Statistics gathering started ").append(connector.getStatsOnMs()).append("ms ago").append("<br />\n");
198                 sb.append("Total connections: ").append(connector.getConnections()).append("<br />\n");
199                 sb.append("Current connections open: ").append(connector.getConnectionsOpen());
200                 sb.append("Max concurrent connections open: ").append(connector.getConnectionsOpenMax()).append("<br />\n");
201                 sb.append("Total connections duration: ").append(connector.getConnectionsDurationTotal()).append("<br />\n");
202                 sb.append("Mean connection duration: ").append(connector.getConnectionsDurationMean()).append("<br />\n");
203                 sb.append("Max connection duration: ").append(connector.getConnectionsDurationMax()).append("<br />\n");
204                 sb.append("Connection duration standard deviation: ").append(connector.getConnectionsDurationStdDev()).append("<br />\n");
205                 sb.append("Total requests: ").append(connector.getRequests()).append("<br />\n");
206                 sb.append("Mean requests per connection: ").append(connector.getConnectionsRequestsMean()).append("<br />\n");
207                 sb.append("Max requests per connection: ").append(connector.getConnectionsRequestsMax()).append("<br />\n");
208                 sb.append("Requests per connection standard deviation: ").append(connector.getConnectionsRequestsStdDev()).append("<br />\n");
209             }
210             else
211             {
212                 sb.append("Statistics gathering off.\n");
213             }
214 
215         }
216 
217         sb.append("<h2>Memory:</h2>\n");
218         sb.append("Heap memory usage: ").append(_memoryBean.getHeapMemoryUsage().getUsed()).append(" bytes").append("<br />\n");
219         sb.append("Non-heap memory usage: ").append(_memoryBean.getNonHeapMemoryUsage().getUsed()).append(" bytes").append("<br />\n");
220 
221         response.setContentType("text/html");
222         PrintWriter pout = response.getWriter();
223         pout.write(sb.toString());
224 
225     }
226 }