DiagnosticsAction.java
001 package com.bea.medrec.actions;
002 
003 import com.bea.medrec.beans.DiagnosticsBean;
004 import com.bea.medrec.utils.ClientException;
005 import com.bea.medrec.utils.MedRecLog4jFactory;
006 import java.lang.reflect.Field;
007 import java.util.*;
008 import javax.naming.Context;
009 import javax.naming.InitialContext;
010 import javax.naming.NamingException;
011 import javax.servlet.http.HttpServletRequest;
012 import javax.servlet.http.HttpServletResponse;
013 import javax.management.MBeanServerConnection;
014 import org.apache.log4j.Logger;
015 import org.apache.struts.action.ActionForm;
016 import org.apache.struts.action.ActionForward;
017 import org.apache.struts.action.ActionMapping;
018 import weblogic.diagnostics.accessor.ColumnInfo;
019 import weblogic.diagnostics.accessor.LogTypes;
020 import weblogic.logging.Severities;
021 import javax.management.ObjectName;
022 import weblogic.management.runtime.WLDFDataAccessRuntimeMBean;
023 import weblogic.management.runtime.WLDFAccessRuntimeMBean;
024 
025 /**
026  * Handles retrieving and organizing diagnotics data.
027  *
028  @author Copyright (c) 2006 by BEA Systems. All Rights Reserved.
029  */
030 public class DiagnosticsAction extends AdminBaseLookupDispatchAction {
031 
032   private static Logger logger =
033       MedRecLog4jFactory.getLogger(DiagnosticsAction.class.getName());
034 
035   public ActionForward execute(ActionMapping mapping,
036                                ActionForm form,
037                                HttpServletRequest request,
038                                HttpServletResponse response)
039     throws ClientException, Exception
040   {
041     logger.debug("method mapping="+
042         request.getParameter(mapping.getParameter()));
043     if (request.getParameter(mapping.getParameter()) == null) {
044       return defaultMethod(mapping, form, request, response);
045     else
046       return super.execute(mapping, form, request, response);
047   }
048 
049  /**
050   <p>Determines method calling based on select submit button.</p>
051   */
052   protected Map getKeyMethodMap() {
053     Map<String,String> map = new HashMap<String,String>();
054     map.put("button.Logs""getLogs");
055     map.put("button.Cancel""cancel");
056     return map;
057   }
058 
059  /**
060   <p>Default action method.</p>
061   *
062   @return ActionForward
063   */
064   public ActionForward defaultMethod(ActionMapping mapping,
065                                      ActionForm form,
066                                      HttpServletRequest request,
067                                      HttpServletResponse response)
068     throws Exception
069   {
070     return loadDiagnosticsPage(mapping, form, request, response);
071   }
072 
073   public ActionForward loadDiagnosticsPage(ActionMapping mapping,
074                                            ActionForm form,
075                                            HttpServletRequest request,
076                                            HttpServletResponse response)
077     throws ClientException, Exception
078   {
079     // local variables
080     DiagnosticsBean diagnosticsBean = (DiagnosticsBean)form;
081     if (diagnosticsBean == nulldiagnosticsBean= new DiagnosticsBean();
082 
083     // create collection of log type options
084     setLogNames(request, diagnosticsBean);
085 
086     // create list of time intervals
087     setTimeSpan(diagnosticsBean);
088 
089     // create list of message severity
090     setSeverity(diagnosticsBean);
091 
092     // Redirect to home view.
093     return mapping.findForward("diagnostics");
094   }
095 
096   private void setLogNames(HttpServletRequest request,
097                            DiagnosticsBean diagnosticsBean)
098       throws Exception {
099     String[] names =
100         getDiagntosicMBean(request).getAvailableDiagnosticDataAccessorNames();
101     Arrays.sort(names);
102     for (int i=0; i<names.length; i++) {
103       String name = names[i];
104       if (name.contains("pop_up_only"))
105         continue;
106       diagnosticsBean.addLogType(name, name);
107     }
108   }
109 
110   private void setTimeSpan(DiagnosticsBean diagnosticsBean)
111       throws NamingException {
112         diagnosticsBean.addTimeSpan("All""0");
113     Context initCtx = new InitialContext();
114     int intervalSpan = ((Integer)initCtx.lookup(
115         "java:comp/env/diagnostics/timeSpan/interval")).intValue();
116     int numOfIntervals = ((Integer)initCtx.lookup(
117         "java:comp/env/diagnostics/timeSpan/numOfintervals")).intValue();
118     int tmpInterval = 0;
119     for (int j=0; j<numOfIntervals; j++) {
120       tmpInterval += intervalSpan;
121       diagnosticsBean.addTimeSpan(String.valueOf(tmpInterval),
122           String.valueOf(tmpInterval));
123     }
124   }
125 
126   private void setSeverity(DiagnosticsBean diagnosticsBean)
127       throws IllegalAccessException {
128     Field[] msgFields = null;
129     diagnosticsBean.addMsgSeverity("All","All");
130     msgFields = Severities.class.getFields();
131     sortFields(msgFields);
132     for (int k=0; k<msgFields.length; k++) {
133       String name = msgFields[k].getName();
134       if (!name.endsWith("_TEXT")) continue;
135       diagnosticsBean.addMsgSeverity((String)msgFields[k].get(name),
136           (String)msgFields[k].get(name));
137     }
138   }
139 
140   public ActionForward getLogs(ActionMapping mapping,
141                                ActionForm form,
142                                HttpServletRequest request,
143                                HttpServletResponse response)
144     throws ClientException, Exception
145   {
146     // local variables
147     DiagnosticsBean diagnosticsBean = (DiagnosticsBean)form;
148     logger.debug(diagnosticsBean.toString());
149     WLDFAccessRuntimeMBean daigRuntime = null;
150     WLDFDataAccessRuntimeMBean accessor = null;
151     ColumnInfo[] colInfo = null;
152     String queryStr = "";
153     long beginTime = 0;
154     long endTime = System.currentTimeMillis();
155     Iterator records = null;
156 
157     try {
158       // get handle on data accessor
159       daigRuntime = getDiagntosicMBean(request);
160        accessor = daigRuntime.lookupWLDFDataAccessRuntime(
161            diagnosticsBean.getLogType());
162       logger.debug("Got WLDFDataAccessRuntimeMBean");
163     catch (Exception ex) {
164       throwClientException(new Exception("Unable to obtain log for "+
165           diagnosticsBean.getLogType()+".  Be sure that logging is properly "+
166           "configured for this component."), mapping, "diagnostics.home");
167     }
168 
169     // construct being and end time filtering
170     if (diagnosticsBean.getTimeSpan() != null
171         && !diagnosticsBean.getTimeSpan().equals("0")) {
172       try {
173         Calendar cal = Calendar.getInstance();
174         cal.add(Calendar.HOUR,
175             Integer.parseInt(diagnosticsBean.getTimeSpan()));
176         endTime = cal.getTimeInMillis();
177         logger.debug("Calculated end time");
178       catch (NumberFormatException nfex) {
179         throw new RuntimeException("Error formatting time bounds", nfex);
180       }
181     }
182 
183     // construct query string for msg severity
184     if (isNotEmpty(diagnosticsBean.getMsgSeverity())
185         && !diagnosticsBean.getMsgSeverity().equals("All")
186         && (diagnosticsBean.getLogType().equals(LogTypes.SERVER_LOG)
187             || diagnosticsBean.getLogType().equals(LogTypes.DOMAIN_LOG))) {
188       queryStr += "SEVERITY = '"+diagnosticsBean.getMsgSeverity()+"'";
189     }
190 
191     // construct query string for msg content search
192     if (isNotEmpty(diagnosticsBean.getSearchCriteria())
193         && (diagnosticsBean.getLogType().equals(LogTypes.SERVER_LOG)
194             || diagnosticsBean.getLogType().equals(LogTypes.DOMAIN_LOG))) {
195       if (queryStr.length() 0)
196         queryStr += " AND";
197       queryStr += " MESSAGE LIKE '%"+diagnosticsBean.getSearchCriteria()+"%'";
198     }
199     logger.debug("Final query string: "+queryStr);
200 
201     // get column names and retrieve records
202     colInfo = accessor.getColumns();
203     records = accessor.retrieveDataRecords(beginTime, endTime, queryStr);
204 
205     ObjectName service = null;
206     ObjectName serverRuntime = null;
207     ObjectName wldfRuntime = null;
208     ObjectName wldfAccessRuntime = null;
209     ObjectName wldfDataAccessRuntime = null;
210     String cursor = null;
211     Object[] rows = null;
212 
213     MBeanServerConnection mbeanServerConnection = getMBeanServerConnection(
214         request);
215     service = new ObjectName("com.bea:Name=RuntimeService,"+
216         "Type=weblogic.management.mbeanservers.runtime.RuntimeServiceMBean");
217     serverRuntime =  (ObjectNamembeanServerConnection.getAttribute(service,
218         "ServerRuntime");
219     wldfRuntime = (ObjectNamembeanServerConnection.getAttribute(serverRuntime,
220         "WLDFRuntime");
221     wldfAccessRuntime = (ObjectNamembeanServerConnection.getAttribute(
222         wldfRuntime, "WLDFAccessRuntime");
223 
224     wldfDataAccessRuntime = (ObjectNamembeanServerConnection.invoke(
225         wldfAccessRuntime, "lookupWLDFDataAccessRuntime",
226         new Object[] { diagnosticsBean.getLogType() },
227         new String[] {"java.lang.String"});
228 
229     logger.debug("Query str: "+queryStr);
230     cursor = (StringmbeanServerConnection.invoke(wldfDataAccessRuntime,
231         "openCursor",
232         new Object[] { queryStr },
233         new String[] {"java.lang.String"});
234 
235     rows = (Object[]) mbeanServerConnection.invoke(
236         wldfDataAccessRuntime,
237         "fetch",
238         new Object[] {cursor},
239         new String[] {"java.lang.String"});
240 
241     logger.debug("Found "+rows.length+" log entries:");
242     Collection<Object> logResults = new ArrayList<Object>();
243 
244     for (int i=0; i<rows.length; i++) {
245       StringBuffer strBuff = new StringBuffer();
246       strBuff.append("Row "+i+1+": ");
247       Object[] cols = (Object[]) rows[i];
248       for (int j=0; j<cols.length; j++) {
249         strBuff.append(" Index "+j+"="+cols[j]);
250       }
251       logger.debug(strBuff.toString());
252     }
253     logResults.add(rows);
254 
255     mbeanServerConnection.invoke(
256         wldfDataAccessRuntime,
257         "closeCursor",
258         new Object[] {cursor},
259         new String[] {"java.lang.String"});
260 
261 
262     // place objects on request to be render by the view
263     logger.debug("Preparing output");
264     request.setAttribute(AdminConstants.LOG_TYPE,
265         diagnosticsBean.getLogType());
266     request.setAttribute(AdminConstants.LOG_COLUMNS, colInfo);
267     request.setAttribute(AdminConstants.LOG_RECORDS, rows);
268 
269     // Redirect to home view.
270     return mapping.findForward("logs");
271   }
272 
273  /**
274   <p>User selected cancel button.</p>
275   *
276   @return ActionForward
277   */
278   public ActionForward cancel(ActionMapping mapping,
279                               ActionForm form,
280                               HttpServletRequest request,
281                               HttpServletResponse response)
282     throws Exception
283   {
284     logger.info("Cancel log retrieval.");
285     ActionForward forward = null;
286     try {
287       forward = mapping.findForward("home");
288     }
289     catch(Exception e) {
290       return handleException(e, request, mapping);
291     }
292     return forward;
293   }
294 
295   // sort view fields
296   private void sortFields(Field[] fields) {
297     Arrays.sort(fields,
298         new Comparator() {
299             public int compare(Object o1, Object o2) {
300               String fname1 = ((Field)o1).getName();
301               String fname2 = ((Field)o2).getName();
302               int n1=fname1.length(), n2=fname2.length();
303               for (int i1=0, i2=0; i1<n1 && i2<n2; i1++, i2++) {
304                   char c1 = fname1.charAt(i1);
305                   char c2 = fname2.charAt(i2);
306                   if (c1 != c2) {
307                       c1 = Character.toUpperCase(c1);
308                       c2 = Character.toUpperCase(c2);
309                       if (c1 != c2) {
310                           c1 = Character.toLowerCase(c1);
311                           c2 = Character.toLowerCase(c2);
312                           if (c1 != c2) {
313                               return c1 - c2;
314                           }
315                       }
316                   }
317                 }
318                 return n1 - n2;
319               }
320           });
321   }
322 }