View Javadoc

1   /*
2    * Copyright 2010-2013 Capgemini Licensed under the Apache License, Version 2.0 (the
3    * "License"); you may not use this file except in compliance with the License.
4    * You may obtain a copy of the License at
5    *
6    * http://www.apache.org/licenses/LICENSE-2.0
7    *
8    * Unless required by applicable law or agreed to in writing, software
9    * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11   * License for the specific language governing permissions and limitations under
12   * the License.
13   */
14  package net.sf.appstatus.web.pages;
15  
16  import static java.lang.Math.round;
17  import static java.util.Collections.sort;
18  import static net.sf.appstatus.web.HtmlUtils.applyLayout;
19  import static net.sf.appstatus.web.HtmlUtils.generateBeginTable;
20  import static net.sf.appstatus.web.HtmlUtils.generateEndTable;
21  import static net.sf.appstatus.web.HtmlUtils.generateHeaders;
22  import static net.sf.appstatus.web.HtmlUtils.generateRow;
23  import static net.sf.appstatus.web.HtmlUtils.json;
24  import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;
25  import static org.apache.commons.lang3.StringUtils.join;
26  
27  import java.io.IOException;
28  import java.io.UnsupportedEncodingException;
29  import java.util.HashMap;
30  import java.util.List;
31  import java.util.Map;
32  
33  import javax.servlet.ServletOutputStream;
34  import javax.servlet.http.HttpServletRequest;
35  import javax.servlet.http.HttpServletResponse;
36  
37  import org.apache.commons.lang3.text.StrBuilder;
38  
39  import net.sf.appstatus.core.services.IService;
40  import net.sf.appstatus.web.StatusWebHandler;
41  
42  public class ServicesPage extends AbstractPage {
43  	private static final String ENCODING = "UTF-8";
44  	private static final String PAGECONTENTLAYOUT = "servicesContentLayout.html";
45  
46  	public ServicesPage() {
47  		Resources.addResource("sparkline.js", "/assets/js/jquery.sparkline.min.js", "application/javascript");
48  		Resources.addResource("services.js", "/assets/js/services.js", "application/javascript");
49  	}
50  
51  	@Override
52  	public void doGet(final StatusWebHandler webHandler, final HttpServletRequest req, final HttpServletResponse resp)
53  			throws UnsupportedEncodingException, IOException {
54  
55  		if (req.getParameter("json") != null) {
56  			doGetJSON(webHandler, req, resp);
57  		} else {
58  			doGetHTML(webHandler, req, resp);
59  		}
60  
61  	}
62  
63  	public void doGetHTML(StatusWebHandler webHandler, HttpServletRequest req, HttpServletResponse resp)
64  			throws UnsupportedEncodingException, IOException {
65  
66  		setup(resp, "text/html");
67  		ServletOutputStream os = resp.getOutputStream();
68  
69  		Map<String, String> valuesMap = new HashMap<String, String>();
70  
71  		List<IService> services = webHandler.getAppStatus().getServices();
72  		sort(services);
73  
74  		StrBuilder sbServicesTable = new StrBuilder();
75  
76  		if (generateBeginTable(sbServicesTable, services.size())) {
77  
78  			generateHeaders(sbServicesTable, "", "Group", "Name", "Hits", "Cache", "Running", "min", "max", "avg",
79  					"nested", "min (c)", "max (c)", "avg (c)", "nested (c)", "Status", "Hit rate");
80  
81  			for (IService service : services) {
82  				generateRow(sbServicesTable, Resources.STATUS_JOB, escapeHtml4(service.getGroup()),
83  						escapeHtml4(service.getName()), service.getHits(),
84  						getCountAndPercent("pie-cache",
85  								new Long[] { service.getCacheHits(), service.getHits() - service.getCacheHits() }),
86  						service.getRunning(), service.getMinResponseTime(), service.getMaxResponseTime(),
87  						round(service.getAvgResponseTime()), round(service.getAvgNestedCalls()),
88  						service.getMinResponseTimeWithCache(), service.getMaxResponseTimeWithCache(),
89  						round(service.getAvgResponseTimeWithCache()), round(service.getAvgNestedCallsWithCache()),
90  						getCountAndPercent("pie-status",
91  								new Long[] { service.getHits() - service.getErrors() - service.getFailures(),
92  										service.getFailures(), service.getErrors() }),
93  						"<span class='graph-rate' values=\"\"></span>");
94  			}
95  
96  			generateEndTable(sbServicesTable, services.size());
97  		}
98  
99  		// generating content
100 		valuesMap.put("servicesTable", sbServicesTable.toString());
101 		String content = applyLayout(valuesMap, PAGECONTENTLAYOUT);
102 
103 		valuesMap.clear();
104 		valuesMap.put("content", content);
105 		valuesMap.put("js", "<script type='text/javascript' src='?resource=services.js'></script>");
106 		// generating page
107 		os.write(getPage(webHandler, valuesMap).getBytes(ENCODING));
108 	}
109 
110 	private void doGetJSON(StatusWebHandler webHandler, HttpServletRequest req, HttpServletResponse resp)
111 			throws UnsupportedEncodingException, IOException {
112 
113 		List<IService> services = webHandler.getAppStatus().getServices();
114 		sort(services);
115 
116 		final ServletOutputStream os = resp.getOutputStream();
117 		os.write("[".getBytes(ENCODING));
118 
119 		boolean first = true;
120 		for (IService service : services) {
121 			if (!first) {
122 				os.write((",").getBytes(ENCODING));
123 			}
124 
125 			os.write(("{ " + join(new String[] { json("group", service.getGroup()), json("name", service.getName()),
126 					json("hits", service.getHits()), json("cacheHits", service.getCacheHits()),
127 					json("running", service.getRunning()), json("minResponseTime", service.getMinResponseTime()),
128 					json("maxResponseTime", service.getMaxResponseTime()),
129 					json("avgResponseTime", service.getAvgResponseTime()),
130 					json("avgNestedCalls", service.getAvgNestedCalls()),
131 					json("minResponseTimeWithCache", service.getMinResponseTimeWithCache()),
132 					json("rate", service.getCurrentRate()) }, ", ") + "}").getBytes(ENCODING));
133 
134 			if (first) {
135 				first = false;
136 			}
137 		}
138 
139 		os.write("]".getBytes(ENCODING));
140 
141 	}
142 
143 	@Override
144 	public void doPost(StatusWebHandler webHandler, HttpServletRequest req, HttpServletResponse resp) {
145 
146 	}
147 
148 	private String getCountAndPercent(String cssClass, Long[] values) {
149 		return "<span class='" + cssClass + "' values='" + join(values, ",") + "' ></span>";
150 	}
151 
152 	@Override
153 	public String getId() {
154 		return "services";
155 	}
156 
157 	@Override
158 	public String getName() {
159 		return "Services";
160 	}
161 
162 	/**
163 	 * Returns a percentage string (including '%'), build with value1/value2.
164 	 *
165 	 * @param value1
166 	 * @param value2
167 	 * @return
168 	 */
169 	private String getPercent(long value1, long value2) {
170 		if (value2 == 0) {
171 			return "(-%)";
172 		}
173 		return " (" + ((100 * value1) / value2) + "%)";
174 	}
175 
176 	private String getRate(double value1) {
177 		double rate = Math.round(value1 * 100) / 100d;
178 
179 		return rate + " hits/s";
180 	}
181 }