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 }