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: 563404 $ $Date: 2007-08-07 02:38:34 -0400 (Tue, 07 Aug 2007) $
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 we assume than no fields were passed and just
168 // filter on the current date.
169 if(fromDateStr == null || toDateStr == null) {
170 // just keep the month date and year
171 cal1.set(Calendar.MILLISECOND, 0);
172 cal1.set(Calendar.MINUTE, 0);
173 cal1.set(Calendar.SECOND, 0);
174 cal1.set(Calendar.HOUR_OF_DAY, 0);
175
176 cal2.set(Calendar.HOUR_OF_DAY, cal2.getMaximum(Calendar.HOUR_OF_DAY));
177 cal2.set(Calendar.MINUTE, cal2.getMaximum(Calendar.MINUTE));
178 cal2.set(Calendar.SECOND, cal2.getMaximum(Calendar.SECOND));
179 cal2.set(Calendar.MILLISECOND, cal2.getMaximum(Calendar.MILLISECOND));
180
181 WebAccessLog.SearchResults matchingItems = chosenLog.getMatchingItems(logToSearch,
182 null, null, null, null, cal1.getTime(), cal2.getTime(), null, Integer.valueOf(criteria.maxResult.intValue()-1));
183 renderRequest.setAttribute("logs", matchingItems.getResults());
184 renderRequest.setAttribute("logLength", new Integer(matchingItems.getLineCount()));
185 renderRequest.setAttribute("maxResult", criteria.maxResult);
186 renderRequest.setAttribute("ignoreDates", Boolean.valueOf(criteria.ignoreDates));
187
188 } else {
189 // Get other search criteria
190 String requestHost = criteria.requestHost;
191 String authUser = criteria.authUser;
192 String requestMethod = criteria.requestMethod;
193 String requestedURI = criteria.requestedURI;
194 String startResult = criteria.startResult;
195 Integer iStartResult = null;
196 Integer iMaxResult = criteria.maxResult;
197 try{
198 iStartResult = Integer.valueOf(startResult);
199 }catch(NumberFormatException e){
200 //ignore
201 }
202
203 boolean ignoreDates = criteria.ignoreDates;
204 if (ignoreDates) {
205 WebAccessLog.SearchResults matchingItems = chosenLog.getMatchingItems(logToSearch,
206 requestHost, authUser, requestMethod, requestedURI, null, null, iStartResult, Integer.valueOf(iMaxResult.intValue()-1));
207 renderRequest.setAttribute("logs", matchingItems.getResults());
208 renderRequest.setAttribute("logLength", new Integer(matchingItems.getLineCount()));
209 } else {
210 Date fromDate = null, toDate = null;
211 // Check if the from and to date format is MM/DD/YYYY
212 DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
213 try {
214 fromDate = df.parse(fromDateStr);
215 // get the requested start date (defaults to 00:00:00:000 for time)
216 cal1.setTime(fromDate);
217 String mmddyyyy = (cal1.get(Calendar.MONTH) < 9 ? "0":"") + (cal1.get(Calendar.MONTH)+1);
218 mmddyyyy += "/"+(cal1.get(Calendar.DAY_OF_MONTH) < 10 ? "0":"") + (cal1.get(Calendar.DAY_OF_MONTH));
219 mmddyyyy += "/"+cal1.get(Calendar.YEAR);
220 if(!mmddyyyy.equals(fromDateStr)) {
221 // This should not arise since date input has been validated using javascript.
222 // If this does occur, ignore dates in search criteria and log a WARNING
223 log.warn("From date must be a date in MM/DD/YYYY format, not '"+fromDateStr+"'. Dates will be ignored.");
224 fromDate = null;
225 }
226 toDate = df.parse(toDateStr);
227 cal2.setTime(toDate);
228 mmddyyyy = (cal2.get(Calendar.MONTH) < 9 ? "0":"") + (cal2.get(Calendar.MONTH)+1);
229 mmddyyyy += "/"+(cal2.get(Calendar.DAY_OF_MONTH) < 10 ? "0":"") + (cal2.get(Calendar.DAY_OF_MONTH));
230 mmddyyyy += "/"+cal2.get(Calendar.YEAR);
231 if(!mmddyyyy.equals(toDateStr)) {
232 // This should not arise since date input has been validated using javascript.
233 // If this does occur, ignore to date in search criteria and log a WARNING
234 log.warn("To date must be a date in MM/DD/YYYY format, not "+toDateStr+"'. Dates will be ignored.");
235 toDate = null;
236 } else {
237 // get the requested end date - Note: must set time to end of day
238 cal2.set(Calendar.HOUR_OF_DAY, cal2.getMaximum(Calendar.HOUR_OF_DAY));
239 cal2.set(Calendar.MINUTE, cal2.getMaximum(Calendar.MINUTE));
240 cal2.set(Calendar.SECOND, cal2.getMaximum(Calendar.SECOND));
241 cal2.set(Calendar.MILLISECOND, cal2.getMaximum(Calendar.MILLISECOND));
242 toDate = cal2.getTime();
243 }
244 } catch (ParseException e) {
245 // Should not occur since date input has been validated using javascript.
246 // If this does occur, ignore from and to dates and log a WARNING
247 log.warn("Error parsing input dates. Dates will be ignored.", e);
248 }
249 if(fromDate == null || toDate == null) {
250 fromDate = toDate = null;
251 }
252 WebAccessLog.SearchResults matchingItems = chosenLog.getMatchingItems(logToSearch,
253 requestHost, authUser, requestMethod, requestedURI, fromDate, toDate, iStartResult, Integer.valueOf(iMaxResult.intValue()-1));
254 renderRequest.setAttribute("logs", matchingItems.getResults());
255 renderRequest.setAttribute("logLength", new Integer(matchingItems.getLineCount()));
256 }
257 renderRequest.setAttribute("ignoreDates", new Boolean(ignoreDates));
258 renderRequest.setAttribute("requestHost", requestHost);
259 renderRequest.setAttribute("authUser", authUser);
260 renderRequest.setAttribute("requestMethod", requestMethod);
261 renderRequest.setAttribute("requestedURI", requestedURI);
262 if(iStartResult != null)renderRequest.setAttribute("startResult", iStartResult);
263 if(iMaxResult != null)renderRequest.setAttribute("maxResult", iMaxResult);
264 }
265 renderRequest.setAttribute("toDate", toDateStr);
266 renderRequest.setAttribute("fromDate", fromDateStr);
267 renderRequest.getPortletSession(true).setAttribute(CRITERIA_KEY, criteria, PortletSession.PORTLET_SCOPE);
268 searchView.include(renderRequest, renderRespose);
269 }
270
271 public void init(PortletConfig portletConfig) throws PortletException {
272 PortletContext pc = portletConfig.getPortletContext();
273 searchView = pc.getRequestDispatcher("/WEB-INF/view/webaccesslogmanager/view.jsp");
274 helpView = pc.getRequestDispatcher("/WEB-INF/view/webaccesslogmanager/help.jsp");
275 super.init(portletConfig);
276 }
277
278 public void processAction(ActionRequest actionRequest,
279 ActionResponse actionResponse) throws PortletException, IOException {
280 //todo: according to portlet spec, all forms should submit to Action not Render
281 }
282 private static class Criteria implements Serializable {
283 Integer maxResult = new Integer(DEFAULT_MAX_RESULTS);
284 String fromDate = null;
285 String toDate = null;
286 boolean ignoreDates = false;
287 String requestHost = null;
288 String authUser = null;
289 String requestMethod = "ANY";
290 String requestedURI = null;
291 String startResult = null;
292 }
293
294 }