All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.jca.as.tracer.HTMLReport Maven / Gradle / Ivy

Go to download

IronJacamar is an implementation of the Java EE Connector Architecture 1.7 specification

There is a newer version: 3.0.10.Final
Show newest version
/*
 * IronJacamar, a Java EE Connector Architecture implementation
 * Copyright 2014, Red Hat Inc, and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.jboss.jca.as.tracer;

import org.jboss.jca.Version;
import org.jboss.jca.core.tracer.TraceEvent;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**
 * HTML report generator for a tracer log
 */
public class HTMLReport
{
   private static final String NEW_LINE = System.getProperty("line.separator", "\n");

   /**
    * Write string
    * @param fw The file writer
    * @param s The string
    * @exception Exception If an error occurs
    */
   static void writeString(FileWriter fw, String s) throws Exception
   {
      for (int i = 0; i < s.length(); i++)
      {
         fw.write((int)s.charAt(i));
      }
   }

   /**
    * Write EOL
    * @param fw The file writer
    * @exception Exception If an error occurs
    */
   static void writeEOL(FileWriter fw) throws Exception
   {
      writeString(fw, NEW_LINE);
   }

   /**
    * Write top-level index.html
    * @param poolNames The pool names
    * @param statuses The overall status of each pool
    * @param ccmStatus The status of the CCM
    * @param ccmPoolStatuses The CCM status of the pools
    * @param version The version information
    * @param fw The file writer
    * @exception Exception If an error occurs
    */
   private static void generateTopLevelIndexHTML(Set poolNames,
                                                 Map statuses,
                                                 TraceEventStatus ccmStatus,
                                                 Map ccmPoolStatuses,
                                                 TraceEvent version,
                                                 FileWriter fw)
      throws Exception
   {
      writeString(fw, "");
      writeEOL(fw);

      writeString(fw, "");
      writeEOL(fw);

      writeString(fw, "");
      writeEOL(fw);

      writeString(fw, "");
      writeEOL(fw);

      writeString(fw, "IronJacamar tracer report");
      writeEOL(fw);

      writeString(fw, "");
      writeEOL(fw);

      writeString(fw, "");
      writeEOL(fw);

      writeString(fw, "

IronJacamar tracer report

"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "
Generated:" + new Date() + "
Data:" + Version.PROJECT + " " + (version != null ? version.getPool() : "Unknown") + "
By:" + Version.FULL_VERSION + "
"); writeEOL(fw); writeString(fw, "

Pool

"); writeEOL(fw); writeString(fw, "
    "); writeEOL(fw); for (String name : poolNames) { TraceEventStatus status = statuses.get(name); writeString(fw, "
  • "); writeString(fw, "
    "); writeString(fw, name); writeString(fw, "
    "); writeEOL(fw); writeString(fw, "
  • "); writeEOL(fw); } writeString(fw, "
"); writeEOL(fw); writeString(fw, "

Lifecycle

"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "

CachedConnectionManager

"); writeEOL(fw); writeString(fw, "
    "); writeEOL(fw); writeString(fw, "
  • Main report
  • "); writeEOL(fw); writeString(fw, "
"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "

Reference

"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "

Other

"); writeEOL(fw); writeString(fw, "
    "); writeEOL(fw); writeString(fw, "
  • Transaction
  • "); writeEOL(fw); writeString(fw, "
"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } /** * Write pool index.html * @param poolName The name of the pool * @param overallStatus The overall status of the pool * @param mcps The managed connection pools * @param statuses The overall status of each connection listener * @param fw The file writer * @exception Exception If an error occurs */ private static void generatePoolIndexHTML(String poolName, TraceEventStatus overallStatus, Set mcps, Map statuses, FileWriter fw) throws Exception { if (overallStatus == null) overallStatus = TraceEventStatus.GREEN; if (mcps == null) mcps = new HashSet(); if (statuses == null) statuses = new TreeMap(); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "Pool: " + poolName + ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "

Pool: " + poolName + "

"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "
Status:
"); writeString(fw, overallStatus.getDescription()); writeString(fw, "
ManagedConnectionPool:"); Iterator mcpIt = mcps.iterator(); while (mcpIt.hasNext()) { String mcp = mcpIt.next(); writeString(fw, mcp); if (mcpIt.hasNext()) writeString(fw, "
"); } writeString(fw, "
"); writeEOL(fw); writeString(fw, "

ConnectionListeners

"); writeEOL(fw); writeString(fw, "
    "); writeEOL(fw); Iterator> it = statuses.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = it.next(); String directory = entry.getKey(); writeString(fw, "
  • "); writeString(fw, "
    "); writeString(fw, directory); writeString(fw, "
    "); writeEOL(fw); writeString(fw, "
  • "); writeEOL(fw); } writeString(fw, "
"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "

Lifecycle

"); writeEOL(fw); writeString(fw, "Report"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "

CachedConnectionManager

"); writeEOL(fw); writeString(fw, "Report"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "Back"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } /** * Write ConnectionListener index.html * @param identifier The identifier * @param data The data * @param status The overall status * @param createCallStack The CREATE callstack * @param destroyCallStack The DESTROY callstack * @param noSDedit Should SDedit functionality be disabled * @param root The root directory * @param fw The file writer * @exception Exception If an error occurs */ private static void generateConnectionListenerIndexHTML(String identifier, List data, TraceEventStatus status, TraceEvent createCallStack, TraceEvent destroyCallStack, boolean noSDedit, String root, FileWriter fw) throws Exception { writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "ConnectionListener: " + identifier + ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "

ConnectionListener: " + identifier + "

"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); if (createCallStack != null) { writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } if (destroyCallStack != null) { writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "
Pool:" + createCallStack.getPool() + "
ManagedConnectionPool:" + createCallStack.getManagedConnectionPool() + "
ManagedConnection:" + createCallStack.getPayload1() + "
Created:" + createCallStack.getTimestamp() + "
Destroyed:" + destroyCallStack.getTimestamp() + "
Status:
"); writeString(fw, status.getDescription()); writeString(fw, "
"); writeEOL(fw); writeString(fw, "

Reports

"); writeEOL(fw); writeString(fw, "
    "); writeEOL(fw); for (Interaction interaction : data) { String durationKey = interaction.getStartTime() + "-" + interaction.getEndTime(); writeString(fw, "
  • "); writeString(fw, "
    "); writeString(fw, durationKey); writeString(fw, "
    "); writeEOL(fw); writeString(fw, "
  • "); writeEOL(fw); FileWriter cl = null; try { File f = new File(root + "/" + durationKey); f.mkdirs(); cl = new FileWriter(f.getAbsolutePath() + "/" + "index.html"); generateConnectionListenerReportHTML(f.getCanonicalPath(), identifier, createCallStack.getPayload1(), interaction, noSDedit, cl); } finally { if (cl != null) { try { cl.flush(); cl.close(); } catch (Exception e) { // Ignore } } } if (status == TraceEventStatus.GREEN && !noSDedit) { FileWriter sdedit = null; try { File f = new File(root + "/" + durationKey); f.mkdirs(); sdedit = new FileWriter(f.getAbsolutePath() + "/" + identifier + ".sdx"); SDeditGenerator.generateSDedit(interaction.getEvents(), sdedit); } finally { if (sdedit != null) { try { sdedit.flush(); sdedit.close(); } catch (Exception e) { // Ignore } } } } } writeString(fw, "
"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); if (createCallStack != null && !createCallStack.getPayload2().equals("")) { writeString(fw, "

CREATE callstack

"); writeEOL(fw); writeString(fw, "
");
         writeEOL(fw);

         writeString(fw, TraceEventHelper.exceptionDescription(createCallStack.getPayload2()));
         writeEOL(fw);

         writeString(fw, "
"); writeEOL(fw); } if (destroyCallStack != null && !destroyCallStack.getPayload1().equals("")) { writeString(fw, "

DESTROY callstack

"); writeEOL(fw); writeString(fw, "
");
         writeEOL(fw);

         writeString(fw, TraceEventHelper.exceptionDescription(destroyCallStack.getPayload1()));
         writeEOL(fw);

         writeString(fw, "
"); writeEOL(fw); } writeString(fw, "Back"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } /** * Write ConnectionListener report * @param root The root directory * @param identifier The identifier * @param mc The managed connection * @param interaction The interaction * @param noSDedit Should SDedit functionality be disabled * @param fw The file writer * @exception Exception If an error occurs */ private static void generateConnectionListenerReportHTML(String root, String identifier, String mc, Interaction interaction, boolean noSDedit, FileWriter fw) throws Exception { writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "ConnectionListener: " + identifier + " (" + interaction.getStartTime() + "-" + interaction.getEndTime() + ")"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "

ConnectionListener: " + identifier + "

"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "
Pool:" + interaction.getPool() + "
ManagedConnectionPool:" + interaction.getManagedConnectionPool() + "
ManagedConnection:" + mc + "
From:" + interaction.getStartTime() + "
To:" + interaction.getEndTime() + "
Thread:" + interaction.getThread() + "
Status:
"); writeString(fw, interaction.getStatus().getDescription()); writeString(fw, "
"); writeEOL(fw); if (!noSDedit) { writeString(fw, "

Sequence diagram

"); writeEOL(fw); if (interaction.getStatus() == TraceEventStatus.GREEN) { writeString(fw, "\"SDedit"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "Generate the image by: sdedit -t png -o "); writeString(fw, root); writeString(fw, "/"); writeString(fw, identifier); writeString(fw, ".png "); writeString(fw, root); writeString(fw, "/"); writeString(fw, identifier); writeString(fw, ".sdx "); writeString(fw, ""); writeEOL(fw); } else { writeString(fw, "See Description or Data for recorded data"); writeEOL(fw); } } writeString(fw, "

Description

"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); for (TraceEvent te : interaction.getEvents()) { writeString(fw, ""); writeEOL(fw); // Timestamp writeString(fw, ""); writeEOL(fw); // Text writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } writeString(fw, ""); writeEOL(fw); writeString(fw, "
TimestampDescription
"); if (TraceEventHelper.isRed(te)) { writeString(fw, "
"); } else if (TraceEventHelper.isYellow(te)) { writeString(fw, "
"); } writeString(fw, Long.toString(te.getTimestamp())); if (TraceEventHelper.isRed(te) || TraceEventHelper.isYellow(te)) writeString(fw, "
"); writeString(fw, "
"); if (TraceEventHelper.isRed(te)) { writeString(fw, "
"); } else if (TraceEventHelper.isYellow(te)) { writeString(fw, "
"); } writeString(fw, TraceEvent.asText(te)); if (TraceEventHelper.isRed(te) || TraceEventHelper.isYellow(te)) writeString(fw, "
"); writeString(fw, "
"); writeEOL(fw); TraceEvent createCallStack = TraceEventHelper.getType(interaction.getEvents(), TraceEvent.CREATE_CONNECTION_LISTENER_GET); if (createCallStack != null && createCallStack.getPayload2() != null && !createCallStack.getPayload2().equals("")) { writeString(fw, "

CREATE callstack

"); writeEOL(fw); writeString(fw, "
");
         writeEOL(fw);

         writeString(fw, TraceEventHelper.exceptionDescription(createCallStack.getPayload2()));
         writeEOL(fw);

         writeString(fw, "
"); writeEOL(fw); } TraceEvent getCallStack = TraceEventHelper.getType(interaction.getEvents(), TraceEvent.GET_CONNECTION_LISTENER, TraceEvent.GET_CONNECTION_LISTENER_NEW, TraceEvent.GET_INTERLEAVING_CONNECTION_LISTENER, TraceEvent.GET_INTERLEAVING_CONNECTION_LISTENER_NEW); if (getCallStack != null && getCallStack.getPayload1() != null && !getCallStack.getPayload1().equals("")) { writeString(fw, "

GET callstack

"); writeEOL(fw); writeString(fw, "
");
         writeEOL(fw);

         writeString(fw, TraceEventHelper.exceptionDescription(getCallStack.getPayload1()));
         writeEOL(fw);

         writeString(fw, "
"); writeEOL(fw); } TraceEvent returnCallStack = TraceEventHelper.getType(interaction.getEvents(), TraceEvent.RETURN_CONNECTION_LISTENER, TraceEvent.RETURN_CONNECTION_LISTENER_WITH_KILL, TraceEvent.RETURN_INTERLEAVING_CONNECTION_LISTENER, TraceEvent.RETURN_INTERLEAVING_CONNECTION_LISTENER_WITH_KILL); if (returnCallStack != null && returnCallStack.getPayload1() != null && !returnCallStack.getPayload1().equals("")) { writeString(fw, "

RETURN callstack

"); writeEOL(fw); writeString(fw, "
");
         writeEOL(fw);

         writeString(fw, TraceEventHelper.exceptionDescription(returnCallStack.getPayload1()));
         writeEOL(fw);

         writeString(fw, "
"); writeEOL(fw); } TraceEvent destroyCallStack = TraceEventHelper.getType(interaction.getEvents(), TraceEvent.DESTROY_CONNECTION_LISTENER_RETURN); if (destroyCallStack != null && destroyCallStack.getPayload1() != null && !destroyCallStack.getPayload1().equals("")) { writeString(fw, "

DESTROY callstack

"); writeEOL(fw); writeString(fw, "
");
         writeEOL(fw);

         writeString(fw, TraceEventHelper.exceptionDescription(destroyCallStack.getPayload1()));
         writeEOL(fw);

         writeString(fw, "
"); writeEOL(fw); } if (TraceEventHelper.hasException(interaction.getEvents())) { writeString(fw, "

Exception

"); writeEOL(fw); for (TraceEvent te : interaction.getEvents()) { if (te.getType() == TraceEvent.EXCEPTION) { writeString(fw, "
");
               writeEOL(fw);

               writeString(fw, TraceEventHelper.exceptionDescription(te.getPayload1()));
               writeEOL(fw);

               writeString(fw, "
"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); } } } writeString(fw, "

Data

"); writeEOL(fw); writeString(fw, "
");
      writeEOL(fw);

      for (TraceEvent te : interaction.getEvents())
      {
         writeString(fw, TraceEventHelper.prettyPrint(te));
         writeEOL(fw);
      }

      writeString(fw, "
"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "Back"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } /** * Write lifecycle.html * @param poolName The name of the pool * @param events The events * @param activeCLs The active connection listeners * @param fw The file writer * @exception Exception If an error occurs */ private static void generateLifecycleHTML(String poolName, List events, Set activeCLs, FileWriter fw) throws Exception { writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "Lifecycle: " + poolName + ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "

Lifecycle: " + poolName + "

"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); for (TraceEvent te : events) { writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); if (!"NONE".equals(te.getConnectionListener())) { if (activeCLs.contains(te.getConnectionListener())) { writeString(fw, ""); } else { writeString(fw, ""); } } else { writeString(fw, ""); } writeEOL(fw); writeString(fw, ""); writeEOL(fw); } writeString(fw, "
TimestampManagedConnectionPoolEventConnectionListener
" + te.getTimestamp() + "" + te.getManagedConnectionPool() + "" + TraceEvent.asText(te) + "" + te.getConnectionListener() + "" + te.getConnectionListener() + "
"); writeEOL(fw); writeString(fw, "

Pool

"); writeEOL(fw); writeString(fw, "Report"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "

CachedConnectionManager

"); writeEOL(fw); writeString(fw, "Report"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "

Data

"); writeEOL(fw); writeString(fw, "
");
      writeEOL(fw);

      for (TraceEvent te : events)
      {
         writeString(fw, TraceEventHelper.prettyPrint(te));
         writeEOL(fw);
      }

      writeString(fw, "
"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "Back"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } /** * Write ccm.html for the CCM * @param events The events * @param status The status * @param path The root path * @param fw The file writer * @exception Exception If an error occurs */ private static void generateCCMHTML(List events, TraceEventStatus status, String path, FileWriter fw) throws Exception { writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "CachedConnectionManager"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "

CachedConnectionManager

"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "
Status:
"); writeString(fw, status.getDescription()); writeString(fw, "
"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); for (TraceEvent te : events) { writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); String callstack = te.getPayload1(); if (te.getType() == TraceEvent.PUSH_CCM_CONTEXT) { callstack += "-push"; } else { callstack += "-pop"; } callstack += ".txt"; writeString(fw, ""); writeEOL(fw); FileWriter report = null; try { report = new FileWriter(path + "/" + callstack); writeString(report, TraceEventHelper.exceptionDescription(te.getPayload2())); writeEOL(report); } finally { if (report != null) { try { report.flush(); report.close(); } catch (Exception e) { // Ignore } } } writeString(fw, ""); writeEOL(fw); } writeString(fw, "
TimestampThreadEventKeyCall stack
" + te.getTimestamp() + "" + te.getThreadId() + "" + TraceEvent.asText(te) + "" + te.getPayload1() + "Link
"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "Back"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } /** * Write ccm.html for pools * @param poolName The name of the pool * @param events The events * @param status The status * @param fw The file writer * @exception Exception If an error occurs */ private static void generateCCMPoolHTML(String poolName, List events, TraceEventStatus status, FileWriter fw) throws Exception { writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "CCM: " + poolName + ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "

CCM: " + poolName + "

"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "
Status:
"); writeString(fw, status.getDescription()); writeString(fw, "
"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); for (TraceEvent te : events) { writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); if (!"NONE".equals(te.getManagedConnectionPool())) { writeString(fw, ""); } else { writeString(fw, ""); } writeEOL(fw); writeString(fw, ""); writeEOL(fw); if (!"NONE".equals(te.getConnectionListener())) { writeString(fw, ""); } else { writeString(fw, ""); } writeEOL(fw); if (!"NONE".equals(te.getPayload1())) { writeString(fw, ""); } else { writeString(fw, ""); } writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } writeString(fw, "
TimestampThreadManagedConnectionPoolEventConnectionListenerConnectionKey
" + te.getTimestamp() + "" + te.getThreadId() + "" + te.getManagedConnectionPool() + "" + TraceEvent.asText(te) + "" + te.getConnectionListener() + "" + te.getPayload1() + "" + te.getPayload2() + "
"); writeEOL(fw); writeString(fw, "

Pool

"); writeEOL(fw); writeString(fw, "Report"); writeEOL(fw); writeString(fw, "

Lifecycle

"); writeEOL(fw); writeString(fw, "Report"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "

Data

"); writeEOL(fw); writeString(fw, "
");
      writeEOL(fw);

      for (TraceEvent te : events)
      {
         writeString(fw, TraceEventHelper.prettyPrint(te));
         writeEOL(fw);
      }

      writeString(fw, "
"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "Back"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } /** * Write toc-c.html for connections * @param events The events * @param fw The file writer * @exception Exception If an error occurs */ private static void generateToCConnection(Map> events, FileWriter fw) throws Exception { writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "Reference: Connection"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "

Reference: Connection

"); writeEOL(fw); writeString(fw, "
    "); writeEOL(fw); for (String id : events.keySet()) { writeString(fw, "
  • " + id + "
  • "); writeEOL(fw); } writeString(fw, "
"); writeEOL(fw); for (Map.Entry> entry : events.entrySet()) { writeString(fw, "

" + entry.getKey() + "

"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); for (TraceEvent te : entry.getValue()) { writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } writeString(fw, "
TimestampConnectionListenerManagedConnectionPoolPool
" + te.getTimestamp() + "" + te.getConnectionListener() + "" + te.getManagedConnectionPool() + "" + te.getPool() + "
"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); } writeString(fw, "

"); writeEOL(fw); writeString(fw, "Back"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } /** * Write toc-mc.html for managed connections * @param events The events * @param fw The file writer * @exception Exception If an error occurs */ private static void generateToCManagedConnection(Map events, FileWriter fw) throws Exception { writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "Reference: ManagedConnection"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "

Reference: ManagedConnection

"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); for (Map.Entry entry : events.entrySet()) { TraceEvent te = entry.getValue(); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } writeString(fw, "
ManagedConnectionConnectionListenerManagedConnectionPoolPool
" + te.getPayload1() + "" + te.getConnectionListener() + "" + te.getManagedConnectionPool() + "" + te.getPool() + "
"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "Back"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } /** * Write toc-cl.html for connection listeners * @param events The events * @param fw The file writer * @exception Exception If an error occurs */ private static void generateToCConnectionListener(Map> events, FileWriter fw) throws Exception { writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "Reference: ConnectionListener"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "

Reference: ConnectionListener

"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); for (Map.Entry> entry : events.entrySet()) { TraceEvent te = entry.getValue().get(0); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } writeString(fw, "
ConnectionListenerManagedConnectionPoolPool
" + te.getConnectionListener() + "" + te.getManagedConnectionPool() + "" + te.getPool() + "
"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "Back"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } /** * Write toc-mcp.html for managed connection pool * @param events The events * @param fw The file writer * @exception Exception If an error occurs */ private static void generateToCManagedConnectionPool(Map> events, FileWriter fw) throws Exception { writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "Reference: ManagedConnectionPool"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "

Reference: ManagedConnectionPool

"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); for (Map.Entry> entry : events.entrySet()) { TraceEvent te = entry.getValue().get(0); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } writeString(fw, "
ManagedConnectionPoolPool
" + te.getManagedConnectionPool() + "" + te.getPool() + "
"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); writeString(fw, "Back"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } /** * Write transaction.html for transactions * @param data The data * @param fw The file writer * @exception Exception If an error occurs */ private static void generateTransaction(Map> data, FileWriter fw) throws Exception { Map txStatus = new TreeMap(); for (Map.Entry> entry : data.entrySet()) { List statuses = new ArrayList(); for (Interaction interaction : entry.getValue()) statuses.add(interaction.getStatus()); txStatus.put(entry.getKey(), TraceEventHelper.mergeStatus(statuses)); } writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "Transaction"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, "

Transaction

"); writeEOL(fw); writeString(fw, "
    "); writeEOL(fw); for (Map.Entry> entry : data.entrySet()) { TraceEventStatus status = txStatus.get(entry.getKey()); writeString(fw, "
  • " + "
    " + entry.getKey() + "
    (" + entry.getValue().size() + ")
  • "); writeEOL(fw); } writeString(fw, "
"); writeEOL(fw); for (Map.Entry> entry : data.entrySet()) { TraceEventStatus status = txStatus.get(entry.getKey()); writeString(fw, "

Transaction:
" + entry.getKey() + "

"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); for (Interaction interaction : entry.getValue()) { writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } writeString(fw, "
StartEndThreadPoolManagedConnectionPoolConnectionListener
" + interaction.getStartTime() + "" + interaction.getEndTime() + "" + interaction.getThread() + "" + interaction.getPool() + "" + interaction.getManagedConnectionPool() + "" + interaction.getConnectionListener() + "
"); writeEOL(fw); writeString(fw, "

"); writeEOL(fw); } writeString(fw, "Back"); writeEOL(fw); writeString(fw, ""); writeEOL(fw); writeString(fw, ""); writeEOL(fw); } /** * Main * @param args The arguments */ public static void main(String[] args) { if (args == null || args.length < 1) { System.out.println("Usage: HTMLReport [-ignore-delist] [-ignore-tracking] " + "[-ignore-incomplete] [-no-sdedit] []"); return; } boolean ignoreDelist = false; boolean ignoreTracking = false; boolean ignoreIncomplete = false; boolean noSDedit = false; int argCount = 0; if ("-ignore-delist".equalsIgnoreCase(args[argCount])) { ignoreDelist = true; argCount++; } if ("-ignore-tracking".equalsIgnoreCase(args[argCount])) { ignoreTracking = true; argCount++; } if ("-ignore-incomplete".equalsIgnoreCase(args[argCount])) { ignoreIncomplete = true; argCount++; } if ("-no-sdedit".equalsIgnoreCase(args[argCount])) { noSDedit = true; argCount++; } File logFile = new File(args[argCount]); FileReader logReader = null; String rootDirectory = "report"; if (args.length > argCount + 1) rootDirectory = args[argCount + 1]; File root = new File(rootDirectory); try { logReader = new FileReader(logFile); root.mkdirs(); List events = TraceEventHelper.getEvents(logReader, root); Map> poolData = TraceEventHelper.getPoolData(TraceEventHelper.filterPoolEvents(events), ignoreDelist, ignoreTracking, ignoreIncomplete); Map> filteredLifecycle = TraceEventHelper.filterLifecycleEvents(events); List filteredCCM = TraceEventHelper.filterCCMEvents(events); Map> filteredCCMPool = TraceEventHelper.filterCCMPoolEvents(events); Map> poolMCPs = TraceEventHelper.poolManagedConnectionPools(events); Map> tocConnections = TraceEventHelper.tocConnections(events); Map tocManagedConnections = TraceEventHelper.tocManagedConnections(events); Map> tocConnectionListeners = TraceEventHelper.tocConnectionListeners(events); Map> tocMCPs = TraceEventHelper.tocManagedConnectionPools(events); // CCM status calculation TraceEventStatus ccmStatus = TraceEventHelper.getCCMStatus(filteredCCM, ignoreIncomplete); Map ccmPoolStatus = new TreeMap(); for (Map.Entry> entry : filteredCCMPool.entrySet()) { ccmPoolStatus.put(entry.getKey(), TraceEventHelper.getCCMPoolStatus(entry.getValue(), ignoreIncomplete)); } // Overall pool status Map overallPoolStatus = new TreeMap(); for (String poolName : filteredLifecycle.keySet()) { List interactions = poolData.get(poolName); overallPoolStatus.put(poolName, TraceEventStatus.GREEN); if (interactions != null) { List statuses = new ArrayList(); for (Interaction interaction : interactions) statuses.add(interaction.getStatus()); overallPoolStatus.put(poolName, TraceEventHelper.mergeStatus(statuses)); } } FileWriter topLevel = null; try { topLevel = new FileWriter(root.getAbsolutePath() + "/" + "index.html"); generateTopLevelIndexHTML(filteredLifecycle.keySet(), overallPoolStatus, ccmStatus, ccmPoolStatus, TraceEventHelper.getVersion(events), topLevel); } finally { if (topLevel != null) { try { topLevel.flush(); topLevel.close(); } catch (Exception e) { // Ignore } } } for (String poolName : filteredLifecycle.keySet()) { List data = poolData.get(poolName); FileWriter pool = null; try { String path = root.getAbsolutePath() + "/" + poolName; File f = new File(path); f.mkdirs(); Map clStatus = new TreeMap(); if (data != null) { Map> clInteractions = TraceEventHelper.getConnectionListenerData(data); Iterator>> dataIt = clInteractions.entrySet().iterator(); while (dataIt.hasNext()) { Map.Entry> dataEntry = dataIt.next(); String identifier = dataEntry.getKey(); // Calculate connection listener status List clStatuses = new ArrayList(); for (Interaction interaction : dataEntry.getValue()) clStatuses.add(interaction.getStatus()); TraceEventStatus currentCLStatus = TraceEventHelper.mergeStatus(clStatuses); clStatus.put(identifier, currentCLStatus); FileWriter cl = null; try { String clPath = path + "/" + identifier; File clF = new File(clPath); clF.mkdirs(); cl = new FileWriter(clF.getAbsolutePath() + "/" + "index.html"); TraceEvent createCallStack = TraceEventHelper.getType(events, identifier, TraceEvent.CREATE_CONNECTION_LISTENER_GET, TraceEvent.CREATE_CONNECTION_LISTENER_PREFILL, TraceEvent.CREATE_CONNECTION_LISTENER_INCREMENTER); TraceEvent destroyCallStack = TraceEventHelper.getType(events, identifier, TraceEvent.DESTROY_CONNECTION_LISTENER_RETURN, TraceEvent.DESTROY_CONNECTION_LISTENER_IDLE, TraceEvent.DESTROY_CONNECTION_LISTENER_INVALID, TraceEvent.DESTROY_CONNECTION_LISTENER_FLUSH, TraceEvent.DESTROY_CONNECTION_LISTENER_ERROR, TraceEvent.DESTROY_CONNECTION_LISTENER_PREFILL, TraceEvent.DESTROY_CONNECTION_LISTENER_INCREMENTER); generateConnectionListenerIndexHTML(identifier, dataEntry.getValue(), currentCLStatus, createCallStack, destroyCallStack, noSDedit, clPath, cl); } finally { if (cl != null) { try { cl.flush(); cl.close(); } catch (Exception e) { // Ignore } } } } } pool = new FileWriter(f.getAbsolutePath() + "/" + "index.html"); generatePoolIndexHTML(poolName, overallPoolStatus.get(poolName), poolMCPs.get(poolName), clStatus, pool); } finally { if (pool != null) { try { pool.flush(); pool.close(); } catch (Exception e) { // Ignore } } } } Set activeCLs = new HashSet(); for (List interactions : poolData.values()) { for (Interaction interaction : interactions) activeCLs.add(interaction.getConnectionListener()); } Iterator>> lifeIt = filteredLifecycle.entrySet().iterator(); while (lifeIt.hasNext()) { Map.Entry> entry = lifeIt.next(); FileWriter lifecycle = null; try { String path = root.getAbsolutePath() + "/" + entry.getKey(); File f = new File(path); f.mkdirs(); lifecycle = new FileWriter(path + "/" + "lifecycle.html"); generateLifecycleHTML(entry.getKey(), entry.getValue(), activeCLs, lifecycle); } finally { if (lifecycle != null) { try { lifecycle.flush(); lifecycle.close(); } catch (Exception e) { // Ignore } } } } FileWriter ccm = null; try { String path = root.getAbsolutePath() + "/CachedConnectionManager"; File f = new File(path); f.mkdirs(); if (filteredCCM == null) filteredCCM = new ArrayList(); if (ccmStatus == null) ccmStatus = TraceEventStatus.GREEN; ccm = new FileWriter(path + "/" + "ccm.html"); generateCCMHTML(filteredCCM, ccmStatus, path, ccm); } finally { if (ccm != null) { try { ccm.flush(); ccm.close(); } catch (Exception e) { // Ignore } } } Iterator ccmIt = filteredLifecycle.keySet().iterator(); while (ccmIt.hasNext()) { String ccmPoolKey = ccmIt.next(); List ccmPoolEvents = filteredCCMPool.get(ccmPoolKey); TraceEventStatus ccmPStatus = ccmPoolStatus.get(ccmPoolKey); ccm = null; try { String path = root.getAbsolutePath() + "/" + ccmPoolKey; File f = new File(path); f.mkdirs(); if (ccmPoolEvents == null) ccmPoolEvents = new ArrayList(); if (ccmPStatus == null) ccmPStatus = TraceEventStatus.GREEN; ccm = new FileWriter(path + "/" + "ccm.html"); generateCCMPoolHTML(ccmPoolKey, ccmPoolEvents, ccmPStatus, ccm); } finally { if (ccm != null) { try { ccm.flush(); ccm.close(); } catch (Exception e) { // Ignore } } } } // Reference FileWriter tocC = null; try { String path = root.getAbsolutePath(); tocC = new FileWriter(path + "/" + "toc-c.html"); generateToCConnection(tocConnections, tocC); } finally { if (tocC != null) { try { tocC.flush(); tocC.close(); } catch (Exception e) { // Ignore } } } FileWriter tocMC = null; try { String path = root.getAbsolutePath(); tocMC = new FileWriter(path + "/" + "toc-mc.html"); generateToCManagedConnection(tocManagedConnections, tocMC); } finally { if (tocMC != null) { try { tocMC.flush(); tocMC.close(); } catch (Exception e) { // Ignore } } } FileWriter tocCL = null; try { String path = root.getAbsolutePath(); tocCL = new FileWriter(path + "/" + "toc-cl.html"); generateToCConnectionListener(tocConnectionListeners, tocCL); } finally { if (tocCL != null) { try { tocCL.flush(); tocCL.close(); } catch (Exception e) { // Ignore } } } FileWriter tocMCP = null; try { String path = root.getAbsolutePath(); tocMCP = new FileWriter(path + "/" + "toc-mcp.html"); generateToCManagedConnectionPool(tocMCPs, tocMCP); } finally { if (tocMCP != null) { try { tocMCP.flush(); tocMCP.close(); } catch (Exception e) { // Ignore } } } // Transaction FileWriter transaction = null; try { List allInteractions = new ArrayList(); for (List interactions : poolData.values()) allInteractions.addAll(interactions); Map> transactionData = TraceEventHelper.getTransactionData(allInteractions); String path = root.getAbsolutePath(); transaction = new FileWriter(path + "/" + "transaction.html"); generateTransaction(transactionData, transaction); } finally { if (transaction != null) { try { transaction.flush(); transaction.close(); } catch (Exception e) { // Ignore } } } } catch (Exception e) { e.printStackTrace(); } finally { if (logReader != null) { try { logReader.close(); } catch (Exception e) { // Ignore } } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy