001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.geronimo.console.logmanager;
019
020 import org.apache.commons.logging.Log;
021 import org.apache.commons.logging.LogFactory;
022 import org.apache.geronimo.console.BasePortlet;
023 import org.apache.geronimo.console.util.PortletManager;
024 import org.apache.geronimo.gbean.AbstractName;
025 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
026 import org.apache.geronimo.management.geronimo.WebAccessLog;
027 import org.apache.geronimo.management.geronimo.WebContainer;
028 import org.apache.geronimo.management.geronimo.WebManager;
029
030 import javax.portlet.ActionRequest;
031 import javax.portlet.ActionResponse;
032 import javax.portlet.PortletConfig;
033 import javax.portlet.PortletContext;
034 import javax.portlet.PortletException;
035 import javax.portlet.PortletRequestDispatcher;
036 import javax.portlet.PortletSession;
037 import javax.portlet.RenderRequest;
038 import javax.portlet.RenderResponse;
039 import javax.portlet.WindowState;
040 import java.io.IOException;
041 import java.io.Serializable;
042 import java.text.DateFormat;
043 import java.text.ParseException;
044 import java.text.SimpleDateFormat;
045 import java.util.Calendar;
046 import java.util.Date;
047 import java.util.LinkedHashMap;
048 import java.util.Map;
049
050 /**
051 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
052 */
053 public class WebAccessLogViewerPortlet extends BasePortlet {
054 private final static String CRITERIA_KEY = "org.apache.geronimo.console.web.log.CRITERIA";
055 private final static Log log = LogFactory.getLog(WebAccessLogViewerPortlet.class);
056 private static final int DEFAULT_MAX_RESULTS = 10;
057
058 protected PortletRequestDispatcher searchView;
059
060 protected PortletRequestDispatcher helpView;
061
062 protected void doHelp(RenderRequest renderRequest,
063 RenderResponse renderRespose) throws PortletException, IOException {
064 helpView.include(renderRequest, renderRespose);
065 }
066
067 protected void doView(RenderRequest renderRequest,
068 RenderResponse renderRespose) throws PortletException, IOException {
069 if (WindowState.MINIMIZED.equals(renderRequest.getWindowState())) {
070 return;
071 }
072
073 WebManager[] managers = PortletManager.getCurrentServer(renderRequest).getWebManagers();
074
075 Criteria criteria = (Criteria) renderRequest.getPortletSession(true).getAttribute(CRITERIA_KEY, PortletSession.PORTLET_SCOPE);
076
077
078 //todo: new
079 Map products = new LinkedHashMap();
080 String chosen = renderRequest.getParameter("selectedContainer");
081 if(chosen != null) { // Carry on to render the results with the right selection
082 renderRequest.setAttribute("selectedContainer", chosen);
083 }
084 WebAccessLog chosenLog = null;
085 if(managers != null) {
086 for (int i = 0; i < managers.length; i++) {
087 WebManager manager = managers[i];
088 AbstractName managerName = PortletManager.getNameFor(renderRequest, manager);
089 WebContainer[] containers = (WebContainer[]) manager.getContainers();
090 if (containers != null) {
091 for (int j = 0; j < containers.length; j++) {
092 WebContainer container = containers[j];
093 AbstractName containerName = PortletManager.getNameFor(renderRequest, container);
094 String combined = managerName+"%"+containerName;
095 if(containers.length == 1) {
096 products.put(manager.getProductName(), combined);
097 } else {
098 products.put(manager.getProductName()+" ("+containerName.getName().get(NameFactory.J2EE_NAME)+")", combined);
099 }
100 if(chosenLog == null) { // will pick the correct match, or the first if no selection is specified
101 if(chosen == null || chosen.equals(combined)) {
102 chosenLog = PortletManager.getWebAccessLog(renderRequest, managerName, containerName);
103 }
104 }
105 }
106 } else {
107 log.error("No web containers found for manager "+manager.getProductName());
108 }
109 }
110 } else {
111 log.error("No web managers found!");
112 }
113 renderRequest.setAttribute("webContainers", products);
114 final String[] logNames = chosenLog.getLogNames();
115 renderRequest.setAttribute("webLogs", logNames);
116 String logToSearch = renderRequest.getParameter("selectedLog");
117 if(logToSearch == null) {
118 logToSearch = logNames[0];
119 } else { //what if the log options for Jetty were showing, but the user picked Tomcat to search? todo: fix this with some AJAX to repopulate the form when container is changed
120 boolean found = false;
121 for (int i = 0; i < logNames.length; i++) {
122 String test = logNames[i];
123 if(test.equals(logToSearch)) {
124 found = true;
125 break;
126 }
127 }
128 if(!found) { // Must has been for the other container -- make it work.
129 logToSearch = logNames[0];
130 }
131 }
132
133 String action = renderRequest.getParameter("action");
134 if (criteria == null || (action != null && !"refresh".equals(action))) {
135 if(criteria == null)
136 criteria = new Criteria();
137
138 String fromDate = renderRequest.getParameter("fromDate");
139 String toDate = renderRequest.getParameter("toDate");
140 String requestHost = renderRequest.getParameter("requestHost");
141 String authUser = renderRequest.getParameter("authUser");
142 String method = renderRequest.getParameter("requestMethod");
143 String uri = renderRequest.getParameter("requestedURI");
144 String result = renderRequest.getParameter("startResult");
145 Integer max = criteria.maxResult;
146 try{
147 max = Integer.parseInt(renderRequest.getParameter("maxResult"));
148 }catch(NumberFormatException e){
149 //ignore
150 }
151 String ignoreDates = renderRequest.getParameter("ignoreDates");
152
153 criteria.fromDate = fromDate == null || fromDate.equals("") ? null : fromDate;
154 criteria.toDate = toDate == null || toDate.equals("") ? null : toDate;
155 criteria.requestHost = requestHost == null || requestHost.equals("") ? null : requestHost;
156 criteria.authUser = authUser == null || authUser.equals("") ? null : authUser;
157 criteria.requestMethod = method == null || method.equals("") ? null : method;
158 criteria.requestedURI = uri == null || uri.equals("") ? null : uri;
159 criteria.startResult = result == null || result.equals("") ? null : result;
160 criteria.maxResult = max;
161 criteria.ignoreDates = ignoreDates != null && !ignoreDates.equals("");
162 }
163 String fromDateStr = criteria.fromDate;
164 String toDateStr = criteria.toDate;
165
166 Calendar cal1 = Calendar.getInstance(), cal2 = Calendar.getInstance();
167 // If not all dates were passed and ignoreDates is not enabled, filter on the current date.
168 // Note: This happens only when the portlet is loaded for the first time. Subsequent invocation (other than
169 // using "Refresh") will have either ignoreDates enabled or both the dates non null.
170 if((fromDateStr == null || toDateStr == null) && !criteria.ignoreDates) {
171 // just keep the month date and year
172 cal1.set(Calendar.MILLISECOND, 0);
173 cal1.set(Calendar.MINUTE, 0);
174 cal1.set(Calendar.SECOND, 0);
175 cal1.set(Calendar.HOUR_OF_DAY, 0);
176
177 cal2.set(Calendar.HOUR_OF_DAY, cal2.getMaximum(Calendar.HOUR_OF_DAY));
178 cal2.set(Calendar.MINUTE, cal2.getMaximum(Calendar.MINUTE));
179 cal2.set(Calendar.SECOND, cal2.getMaximum(Calendar.SECOND));
180 cal2.set(Calendar.MILLISECOND, cal2.getMaximum(Calendar.MILLISECOND));
181
182 WebAccessLog.SearchResults matchingItems = chosenLog.getMatchingItems(logToSearch,
183 null, null, null, null, cal1.getTime(), cal2.getTime(), null, Integer.valueOf(criteria.maxResult.intValue()-1));
184 renderRequest.setAttribute("logs", matchingItems.getResults());
185 renderRequest.setAttribute("logLength", new Integer(matchingItems.getLineCount()));
186 renderRequest.setAttribute("maxResult", criteria.maxResult);
187 renderRequest.setAttribute("ignoreDates", Boolean.valueOf(criteria.ignoreDates));
188
189 } else {
190 // Get other search criteria
191 String requestHost = criteria.requestHost;
192 String authUser = criteria.authUser;
193 String requestMethod = criteria.requestMethod;
194 String requestedURI = criteria.requestedURI;
195 String startResult = criteria.startResult;
196 Integer iStartResult = null;
197 Integer iMaxResult = criteria.maxResult;
198 try{
199 iStartResult = Integer.valueOf(startResult);
200 }catch(NumberFormatException e){
201 //ignore
202 }
203
204 boolean ignoreDates = criteria.ignoreDates;
205 if (ignoreDates) {
206 WebAccessLog.SearchResults matchingItems = chosenLog.getMatchingItems(logToSearch,
207 requestHost, authUser, requestMethod, requestedURI, null, null, iStartResult, Integer.valueOf(iMaxResult.intValue()-1));
208 renderRequest.setAttribute("logs", matchingItems.getResults());
209 renderRequest.setAttribute("logLength", new Integer(matchingItems.getLineCount()));
210 } else {
211 Date fromDate = null, toDate = null;
212 // Check if the from and to date format is MM/DD/YYYY
213 DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
214 try {
215 fromDate = df.parse(fromDateStr);
216 // get the requested start date (defaults to 00:00:00:000 for time)
217 cal1.setTime(fromDate);
218 String mmddyyyy = (cal1.get(Calendar.MONTH) < 9 ? "0":"") + (cal1.get(Calendar.MONTH)+1);
219 mmddyyyy += "/"+(cal1.get(Calendar.DAY_OF_MONTH) < 10 ? "0":"") + (cal1.get(Calendar.DAY_OF_MONTH));
220 mmddyyyy += "/"+cal1.get(Calendar.YEAR);
221 if(!mmddyyyy.equals(fromDateStr)) {
222 // This should not arise since date input has been validated using javascript.
223 // If this does occur, ignore dates in search criteria and log a WARNING
224 log.warn("From date must be a date in MM/DD/YYYY format, not '"+fromDateStr+"'. Dates will be ignored.");
225 fromDate = null;
226 }
227 toDate = df.parse(toDateStr);
228 cal2.setTime(toDate);
229 mmddyyyy = (cal2.get(Calendar.MONTH) < 9 ? "0":"") + (cal2.get(Calendar.MONTH)+1);
230 mmddyyyy += "/"+(cal2.get(Calendar.DAY_OF_MONTH) < 10 ? "0":"") + (cal2.get(Calendar.DAY_OF_MONTH));
231 mmddyyyy += "/"+cal2.get(Calendar.YEAR);
232 if(!mmddyyyy.equals(toDateStr)) {
233 // This should not arise since date input has been validated using javascript.
234 // If this does occur, ignore to date in search criteria and log a WARNING
235 log.warn("To date must be a date in MM/DD/YYYY format, not "+toDateStr+"'. Dates will be ignored.");
236 toDate = null;
237 } else {
238 // get the requested end date - Note: must set time to end of day
239 cal2.set(Calendar.HOUR_OF_DAY, cal2.getMaximum(Calendar.HOUR_OF_DAY));
240 cal2.set(Calendar.MINUTE, cal2.getMaximum(Calendar.MINUTE));
241 cal2.set(Calendar.SECOND, cal2.getMaximum(Calendar.SECOND));
242 cal2.set(Calendar.MILLISECOND, cal2.getMaximum(Calendar.MILLISECOND));
243 toDate = cal2.getTime();
244 }
245 } catch (ParseException e) {
246 // Should not occur since date input has been validated using javascript.
247 // If this does occur, ignore from and to dates and log a WARNING
248 log.warn("Error parsing input dates. Dates will be ignored.", e);
249 }
250 if(fromDate == null || toDate == null) {
251 fromDate = toDate = null;
252 }
253 WebAccessLog.SearchResults matchingItems = chosenLog.getMatchingItems(logToSearch,
254 requestHost, authUser, requestMethod, requestedURI, fromDate, toDate, iStartResult, Integer.valueOf(iMaxResult.intValue()-1));
255 renderRequest.setAttribute("logs", matchingItems.getResults());
256 renderRequest.setAttribute("logLength", new Integer(matchingItems.getLineCount()));
257 }
258 renderRequest.setAttribute("ignoreDates", new Boolean(ignoreDates));
259 renderRequest.setAttribute("requestHost", requestHost);
260 renderRequest.setAttribute("authUser", authUser);
261 renderRequest.setAttribute("requestMethod", requestMethod);
262 renderRequest.setAttribute("requestedURI", requestedURI);
263 if(iStartResult != null)renderRequest.setAttribute("startResult", iStartResult);
264 if(iMaxResult != null)renderRequest.setAttribute("maxResult", iMaxResult);
265 }
266 renderRequest.setAttribute("toDate", toDateStr);
267 renderRequest.setAttribute("fromDate", fromDateStr);
268 renderRequest.getPortletSession(true).setAttribute(CRITERIA_KEY, criteria, PortletSession.PORTLET_SCOPE);
269 searchView.include(renderRequest, renderRespose);
270 }
271
272 public void init(PortletConfig portletConfig) throws PortletException {
273 PortletContext pc = portletConfig.getPortletContext();
274 searchView = pc.getRequestDispatcher("/WEB-INF/view/webaccesslogmanager/view.jsp");
275 helpView = pc.getRequestDispatcher("/WEB-INF/view/webaccesslogmanager/help.jsp");
276 super.init(portletConfig);
277 }
278
279 public void processAction(ActionRequest actionRequest,
280 ActionResponse actionResponse) throws PortletException, IOException {
281 String[] paramNames = {"action",
282 "fromDate",
283 "toDate",
284 "ignoreDates",
285 "requestHost",
286 "authUser",
287 "requestMethod",
288 "requestedURI",
289 "startResult",
290 "maxResult"};
291 // copy all action parameters to render parameters
292 for(int i = 0; i < paramNames.length; i++) {
293 if(actionRequest.getParameter(paramNames[i]) != null) {
294 actionResponse.setRenderParameter(
295 paramNames[i],
296 actionRequest.getParameter(paramNames[i]));
297 }
298 }
299 }
300 private static class Criteria implements Serializable {
301 Integer maxResult = new Integer(DEFAULT_MAX_RESULTS);
302 String fromDate = null;
303 String toDate = null;
304 boolean ignoreDates = false;
305 String requestHost = null;
306 String authUser = null;
307 String requestMethod = "ANY";
308 String requestedURI = null;
309 String startResult = null;
310 }
311
312 }