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

lrgs.lrgsmon.DetailReportGenerator Maven / Gradle / Ivy

Go to download

A collection of software for aggregatting and processing environmental data such as from NOAA GOES satellites.

The newest version!
/*
*  $Id$
*/
package lrgs.lrgsmon;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.ResourceBundle;
import java.util.TimeZone;
import java.util.Properties;

import ilex.util.EnvExpander;
import ilex.util.Logger;
import ilex.util.StringPair;
import ilex.xml.XmlOutputStream;

import lrgs.rtstat.RtStat;
import lrgs.statusxml.LrgsStatusSnapshotExt;
import lrgs.apistatus.AttachedProcess;
import lrgs.apistatus.QualityMeasurement;
import lrgs.lrgsmain.LrgsInputInterface;

/**
This class writes the detail report for a single LRGS.
*/
public class DetailReportGenerator
{
	private static ResourceBundle labels = 
		RtStat.getLabels();
	private static ResourceBundle genericLabels = 
		RtStat.getGenericLabels();
	/** Used to format dates in the HTML report header. */
	private SimpleDateFormat headerDF;

	/** Used to format dates in columns in the HTML report. */
	private SimpleDateFormat columnDF;

	/** Local copy of XML output stream */
	private XmlOutputStream xos;

	/** Used to format percentages */
	private DecimalFormat pctFormat = new DecimalFormat("###.##");

	/** Name of image file to place in output. */
	private String imageFile;

	// convenient constants used within HTML:
	private static final String top = "vertical-align: top; ";
	private static final String right  = "text-align: right; ";
	private static final String left   = "text-align: left; ";
	private static final String center = "text-align: center; ";
	private static final String bold   = "font-weight: bold; ";
	private static final String ital   = "font-style: italic; ";

	private static final String redStatus
		= "color: red; font-weight: bold; background-color: black; ";
	private static final String yellowStatus
		= "color: yellow; font-weight: bold; background-color: black; ";
	public boolean showNetworkDcpDetail = false;

	/** This is the default header to use if no file is provided. */
	private String defaultHeader = 
       "

LRGS: ${HOSTNAME}

\n" + "
\n" + " UTC: $DATE(MMMM dd, yyyy HH:mm:ss) (Day $DATE(DDD))\n" + "
\n" + "
" + labels.getString( "DetailReportGenerator.timeReportedLrgs") +"
\n" + "
System Status: ${SYSTEMSTAT}
\n" + "
LRGS Version: ${LRGSVERSION}
\n" + "
\n"; /** HTML header to include in report. */ private String header; /** Constructs a new DetailReportGenerator */ public DetailReportGenerator(String imageFile) { headerDF = new SimpleDateFormat( "MMMM dd, yyyy HH:mm:ss '(Day ' DDD')'"); headerDF.setTimeZone(TimeZone.getTimeZone("UTC")); columnDF = new SimpleDateFormat("MM/dd HH:mm:ss"); columnDF.setTimeZone(TimeZone.getTimeZone("UTC")); this.imageFile = imageFile; this.header = defaultHeader; } /** * Sets the header to the contents of a named file. * @param filename the header file name. * @throws IOException if file can't be read. */ public void setHeader(String filename) throws IOException { if (filename == null) { header = defaultHeader; return; } File f = new File(filename); FileReader fr = new FileReader(f); BufferedReader br = new BufferedReader(fr); StringBuffer sb = new StringBuffer((int)f.length()); String line; while( (line = br.readLine()) != null) sb.append(line + "\n"); br.close(); fr.close(); header = sb.toString(); } /** Writes the detail report. */ public void write(File output, String host, LrgsStatusSnapshotExt status, int scanSeconds) { // Logger.instance().debug1("Generating detail report for " + host); FileOutputStream fos = null; try { File tmp = new File(output.getPath() + ".tmp"); fos = new FileOutputStream(tmp); XmlOutputStream xos = new XmlOutputStream(fos, "html"); writeReport(xos, host, status, scanSeconds); fos.close(); fos = null; if (!tmp.renameTo(output)) { // On windows, have to explicitely delete before rename. output.delete(); if (!tmp.renameTo(output)) { Logger.instance().warning( "LRGS Status report move failed. This can happen on a " + "Windows LRGS if the LRGSHOME directory is being " + "dynamically scanned by your AV. Recommend removing " + "the LRGSHOME directory from the AV scan."); } } } catch(IOException ex) { Logger.instance().warning("Cannot write " + output.getPath() + ": " + ex); } finally { if (fos != null) { try { fos.close(); } catch(IOException ex){} } } } public void writeReport(XmlOutputStream xos, String host, LrgsStatusSnapshotExt status, int scanSeconds) throws IOException { // Define the styles to be used in the output: // Reverse Video OK & Error values String revOK = "color: rgb(51,255,51); font-weight: bold; background-color: black; "; String revERR = "color: rgb(255,255,51); font-weight: bold; background-color: black; "; String thStyle = top + center + bold + ital; String thCol0Style = "vertical-align: top; text-align: right; " + "font-weight: bold; font-style: italic;"; this.xos = xos; xos.startElement("html"); // HTML Header xos.startElement("head"); xos.writeElement("title", host); if (scanSeconds > 0) xos.writeElement("meta", "http-equiv", "refresh", "CONTENT", "" + scanSeconds, null); xos.endElement("head"); xos.startElement("body", "style", "background-color: white;"); // First part of body is the report header, formatted in a table. writeReportHeader(xos, host, status); StringPair sp4[] = new StringPair[4]; sp4[0] = new StringPair("cellpadding", "2"); sp4[1] = new StringPair("cellspacing", "2"); sp4[2] = new StringPair("border", "1"); sp4[3] = new StringPair("style", "text-align: left; width: 100%;"); xos.startElement("table", sp4); xos.startElement("tr"); xos.startElement("td"); sp4[0] = new StringPair("cellpadding", "2"); sp4[1] = new StringPair("cellspacing", "2"); sp4[2] = new StringPair("border", "0"); sp4[3] = new StringPair("style", "width: 100%;"); xos.startElement("table", sp4); xos.startElement("tr"); xos.startElement("td", "colspan", "7"); xos.writeElement("h3", "style",center, labels.getString( "DetailReportGenerator.archiveStatistics")); xos.endElement("td"); xos.endElement("tr"); xos.startElement("tr"); String labelStyle = right + "width: 20%;"; xos.writeElement("td", "style", labelStyle, labels.getString("DetailReportGenerator.messagesStorage")); xos.writeElement("td", "style", left + revOK + "width: 10%", ""+status.lss.arcStats.dirSize); xos.writeElement("td", "style", labelStyle,labels.getString( "DetailReportGenerator.oldestMsgTime")); xos.writeElement("td", "style", left + revOK + "width: 16%", columnDF.format( new Date(status.lss.arcStats.oldestMsgTime * 1000L))); xos.writeElement("td", "style", labelStyle,labels.getString( "DetailReportGenerator.nextIdx")); xos.writeElement("td", "style", left + revOK + "width: 10%", ""+status.lss.arcStats.dirNext); xos.endElement("tr"); xos.endElement("table"); xos.endElement("td"); xos.endElement("tr"); // Hourly Data Collection Statistics Table xos.startElement("tr"); xos.startElement("td"); sp4[0] = new StringPair("style", left + "width: 100%;"); sp4[1] = new StringPair("border", "0"); sp4[2] = new StringPair("cellspacing", "2"); sp4[3] = new StringPair("cellpadding", "2"); xos.startElement("table", sp4); xos.startElement("tr"); xos.startElement("td", "colspan", "9"); xos.writeElement("h3", "style", center,labels.getString( "DetailReportGenerator.hourlyDCStat")); xos.endElement("td"); xos.endElement("tr"); // Row with hour names xos.startElement("tr"); xos.writeElement("th", "style", thStyle + right, labels.getString("DetailReportGenerator.hour")); int hr = (status.lss.currentHour + 17) % 24; for(int i=0; i<8; i++) { String hrString = "" + hr + "-" + ((hr+1)%24); xos.writeElement("th", "style", thStyle, hrString); hr = (hr + 1) % 24; } xos.endElement("tr"); QualityMeasurement qual[] = status.getDownlinkQualityHistory( LrgsInputInterface.DL_DOMSAT); if (qual != null) { if (status.majorVersion < 5) qual = status.lss.qualMeas; xos.startElement("tr"); xos.writeElement("td", "style", right, "DOMSAT (Good/" + (status.majorVersion < 5 ? "Dropped):" : "ParErr):")); hr = (status.lss.currentHour + 17) % 24; for(int i=0; i<8; i++) { int g = qual[hr] != null ? qual[hr].numGood : 0; String v = "" + g; int e = qual[hr] != null ? qual[hr].numDropped : 0; if (e != 0) v = v + " / " + e; xos.writeElement("td", "style", revOK + center, v); hr = (hr + 1) % 24; } xos.endElement("tr"); } qual = status.getDownlinkQualityHistory( LrgsInputInterface.DL_NETBAK); if (qual != null) { qual = status.lss.qualMeas; xos.startElement("tr"); xos.writeElement("td", "style", right, "Old NetBack (Recovered):"); hr = (status.lss.currentHour + 17) % 24; for(int i=0; i<8; i++) { String v = "" + (qual[hr] != null ? qual[hr].numRecovered : 0); xos.writeElement("td", "style", revOK + center, v); hr = (hr + 1) % 24; } xos.endElement("tr"); } if ((status.majorVersion > 5 || (status.majorVersion == 5 && status.minorVersion >= 3)) && status.getDownlinkQualityHistory( LrgsInputInterface.DL_DOMSAT) != null && status.domsatDropped != null) { xos.startElement("tr"); xos.writeElement("td", "style", right, "DOMSAT Dropped:"); hr = (status.lss.currentHour + 17) % 24; for(int i=0; i<8; i++) { String v = "" + status.domsatDropped[hr]; xos.writeElement("td", "style", revOK + center, v); hr = (hr + 1) % 24; } xos.endElement("tr"); } // If there is a DRGS connection, print an extra row for it. qual = status.getDownlinkQualityHistory(LrgsInputInterface.DL_DRGS); if (qual != null && status.getDownlinkQualityHistory( LrgsInputInterface.DL_DRGSCON) != null) { xos.startElement("tr"); xos.writeElement("td", "style", right, "GOES DRGS" + (status.majorVersion < 5 ? ":" : " (Good/ParErr):")); hr = (status.lss.currentHour + 17) % 24; for(int i=0; i<8; i++) { int g = qual[hr] != null ? qual[hr].numGood : 0; String v = "" + g; if (status.majorVersion >= 5) { int e = qual[hr] != null ? qual[hr].numDropped : 0; if (e != 0) v = v + " / " + e; } xos.writeElement("td", "style", revOK + center, v); hr = (hr + 1) % 24; } xos.endElement("tr"); } // If there is a GR3110 connection, print an extra row for it. qual = status.getDownlinkQualityHistory(LrgsInputInterface.DL_GR3110); if (qual != null) { xos.startElement("tr"); xos.writeElement("td", "style", right, "GR3110"); hr = (status.lss.currentHour + 17) % 24; for(int i=0; i<8; i++) { int g = qual[hr] != null ? qual[hr].numGood : 0; String v = "" + g; int e = qual[hr] != null ? qual[hr].numDropped : 0; if (e != 0) v = v + " / " + e; xos.writeElement("td", "style", revOK + center, v); hr = (hr + 1) % 24; } xos.endElement("tr"); } // If there is a DDS Recv connection, print an extra row for it. qual = status.getDownlinkQualityHistory(LrgsInputInterface.DL_DDS); if (qual != null) { xos.startElement("tr"); xos.writeElement("td", "style", right, "DDS Recv (Good/ParErr):"); hr = (status.lss.currentHour + 17) % 24; for(int i=0; i<8; i++) { int g = qual[hr] != null ? qual[hr].numGood : 0; String v = "" + g; int e = qual[hr] != null ? qual[hr].numDropped : 0; if (e != 0) v = v + " / " + e; xos.writeElement("td", "style", revOK + center, v); hr = (hr + 1) % 24; } xos.endElement("tr"); } // If there is a Secondary DDS Recv connection, print an extra row for it. qual = status.getDownlinkQualityHistory(LrgsInputInterface.DL_DDS_SECONDRAY); if (qual != null) { int j = 0; String strArr[] = new String[8]; hr = (status.lss.currentHour + 17) % 24; for(int i=0; i<8; i++) { int g = qual[hr] != null ? qual[hr].numGood : 0; String v = "" + g; int e = qual[hr] != null ? qual[hr].numDropped : 0; if (e != 0) v = v + " / " + e; hr = (hr + 1) % 24; strArr[i]=v; if(v.equalsIgnoreCase("0")) j++; } if(j!=8) { xos.startElement("tr"); xos.writeElement("td", "style", right, "DDS Recv:Secondary (Good/ParErr):"); for(int i=0;i<8;i++) { xos.writeElement("td", "style", revOK + center, strArr[i]); } xos.endElement("tr"); } } // If there is an LRIT Interface, print an extra row for it. qual = status.getDownlinkQualityHistory( LrgsInputInterface.DL_LRIT); if (qual != null) { xos.startElement("tr"); xos.writeElement("td", "style", right, "LRIT (Good/ParErr):"); hr = (status.lss.currentHour + 17) % 24; for(int i=0; i<8; i++) { int g = qual[hr] != null ? qual[hr].numGood : 0; String v = "" + g; int e = qual[hr] != null ? qual[hr].numDropped : 0; if (e != 0) v = v + " / " + e; xos.writeElement("td", "style", revOK + center, v); hr = (hr + 1) % 24; } xos.endElement("tr"); } // If there is a NOAAPORT Interface, print an extra row for it. qual = status.getDownlinkQualityHistory( LrgsInputInterface.DL_NOAAPORT); if (qual != null) { xos.startElement("tr"); xos.writeElement("td", "style", right, "NOAAPORT (Good/ParErr):"); hr = (status.lss.currentHour + 17) % 24; for(int i=0; i<8; i++) { int g = qual[hr] != null ? qual[hr].numGood : 0; String v = "" + g; int e = qual[hr] != null ? qual[hr].numDropped : 0; if (e != 0) v = v + " / " + e; xos.writeElement("td", "style", revOK + center, v); hr = (hr + 1) % 24; } xos.endElement("tr"); } // If there is a Network DCP main, print an extra row for it. qual = status.getDownlinkQualityHistory( LrgsInputInterface.DL_NETWORKDCP); if (qual != null) { xos.startElement("tr"); xos.writeElement("td", "style", right, "Network DCP (Good/ParErr):"); hr = (status.lss.currentHour + 17) % 24; for(int i=0; i<8; i++) { int g = qual[hr] != null ? qual[hr].numGood : 0; String v = "" + g; if (status.majorVersion >= 5) { int e = qual[hr] != null ? qual[hr].numDropped : 0; if (e != 0) v = v + " / " + e; } xos.writeElement("td", "style", revOK + center, v); hr = (hr + 1) % 24; } xos.endElement("tr"); } // If there is a Iridium, print an extra row for it. qual = status.getDownlinkQualityHistory( LrgsInputInterface.DL_IRIDIUM); if (qual != null) { xos.startElement("tr"); xos.writeElement("td", "style", right, "Iridium (Good/Has Errors):"); hr = (status.lss.currentHour + 17) % 24; for(int i=0; i<8; i++) { int g = qual[hr] != null ? qual[hr].numGood : 0; String v = "" + g; if (status.majorVersion >= 5) { int e = qual[hr] != null ? qual[hr].numDropped : 0; if (e != 0) v = v + " / " + e; } xos.writeElement("td", "style", revOK + center, v); hr = (hr + 1) % 24; } xos.endElement("tr"); } // If there is a DCP_SESSION_MGR, print an extra row for it. qual = status.getDownlinkQualityHistory( LrgsInputInterface.DL_SESSIONMGR); if (qual != null) { xos.startElement("tr"); xos.writeElement("td", "style", right, "DCP Polling Sessions:"); hr = (status.lss.currentHour + 17) % 24; for(int i=0; i<8; i++) { int g = qual[hr] != null ? qual[hr].numGood : 0; String v = "" + g; if (status.majorVersion >= 5) { int e = qual[hr] != null ? qual[hr].numDropped : 0; if (e != 0) v = v + " / " + e; } xos.writeElement("td", "style", revOK + center, v); hr = (hr + 1) % 24; } xos.endElement("tr"); } // If there is a EDL_INPUT, print an extra row for it. qual = status.getDownlinkQualityHistory(LrgsInputInterface.DL_EDL); if (qual != null) { xos.startElement("tr"); xos.writeElement("td", "style", right, "EDL Ingest:"); hr = (status.lss.currentHour + 17) % 24; for(int i=0; i<8; i++) { int g = qual[hr] != null ? qual[hr].numGood : 0; String v = "" + g; if (status.majorVersion >= 5) { int e = qual[hr] != null ? qual[hr].numDropped : 0; if (e != 0) v = v + " / " + e; } xos.writeElement("td", "style", revOK + center, v); hr = (hr + 1) % 24; } xos.endElement("tr"); } // Print row with number of messages ARCHIVED qual = status.lss.qualMeas; xos.startElement("tr"); xos.writeElement("td", "style", right, status.majorVersion < 5 ? "Archived:" : "Archived (Good/ParErr):"); hr = (status.lss.currentHour + 17) % 24; for(int i=0; i<8; i++) { int g = qual[hr] != null ? qual[hr].numGood : 0; String v = "" + g; if (status.majorVersion >= 5) { int e = qual[hr] != null ? qual[hr].numDropped : 0; if (e != 0) v = v + " / " + e; } xos.writeElement("td", "style", revOK + center, v); hr = (hr + 1) % 24; } xos.endElement("tr"); xos.endElement("table"); xos.endElement("td"); xos.endElement("tr"); // Downlink Statistics Table xos.startElement("tr"); xos.startElement("td"); sp4[0] = new StringPair("style", left + "width: 100%;"); sp4[1] = new StringPair("border", "0"); sp4[2] = new StringPair("cellspacing", "2"); sp4[3] = new StringPair("cellpadding", "2"); xos.startElement("table", sp4); xos.startElement("tr"); xos.startElement("td", "colspan", "6"); xos.writeElement("h3", "style", center, labels.getString( "DetailReportGenerator.downlinkStats")); xos.endElement("td"); xos.endElement("tr"); xos.startElement("tr"); xos.writeElement("th", "style", thStyle, labels.getString( "DetailReportGenerator.downlinkName")); xos.writeElement("th", "style", thStyle, labels.getString( "DetailReportGenerator.lastMsgRecvT")); // xos.writeElement("th", "style", thStyle, labels.getString( // "DetailReportGenerator.linkType")); xos.writeElement("th", "style", thStyle, labels.getString( "DetailReportGenerator.lastSeqNum")); xos.writeElement("th", "style", thStyle, labels.getString( "DetailReportGenerator.linkStatus")); xos.writeElement("th", "style", thStyle, labels.getString( "DetailReportGenerator.linkParams")); xos.endElement("tr"); if (status.lss.downLinks != null) { for(int i=0; i 0) ? "BER="+v : ""); xos.endElement("tr");*/ } } xos.endElement("table"); xos.endElement("td"); xos.endElement("tr"); xos.startElement("tr"); xos.startElement("td"); sp4[0] = new StringPair("style", left + "width: 100%;"); sp4[1] = new StringPair("border", "0"); sp4[2] = new StringPair("cellspacing", "2"); sp4[3] = new StringPair("cellpadding", "2"); xos.startElement("table", sp4); xos.startElement("tr"); xos.startElement("td", "colspan", "7"); xos.writeElement("h3", "style", center, labels.getString("DetailReportGenerator.clientStats")); xos.endElement("td"); xos.endElement("tr"); xos.startElement("tr"); xos.writeElement("th", "style", thStyle, labels.getString("DetailReportGenerator.slot")); xos.writeElement("th", "style", thStyle, labels.getString("DetailReportGenerator.hostName")); // xos.writeElement("th", "style", thStyle, // labels.getString("DetailReportGenerator.clientType")); xos.writeElement("th", "style", thStyle, labels.getString("DetailReportGenerator.user")); xos.writeElement("th", "style", thStyle, labels.getString("DetailReportGenerator.msgCount")); xos.writeElement("th", "style", thStyle, labels.getString("DetailReportGenerator.lastActivityTime")); xos.writeElement("th", "style", thStyle, labels.getString("DetailReportGenerator.lastMsgTime")); xos.writeElement("th", "style", thStyle, labels.getString("DetailReportGenerator.status")); xos.endElement("tr"); if (status.lss.attProcs != null) { for(int i=0; i"); //xos.writeElement("br", null); } private String fmtColTime(int timet) { if (timet <= 0) return "-"; return columnDF.format(new Date(timet*1000L)); } private void writeReportHeader(XmlOutputStream xos, String host, LrgsStatusSnapshotExt status) throws IOException { Properties p = new Properties(System.getProperties()); p.setProperty("IMAGEFILE", imageFile); p.setProperty("HOSTNAME", host); if (status.fullVersion == null) p.setProperty("LRGSVERSION", "" + status.majorVersion + "." + status.minorVersion); else p.setProperty("LRGSVERSION", status.fullVersion); p.setProperty("TZ", "UTC"); String s = status.systemStatus; if (s.startsWith("R:")) { p.setProperty("STATSTYLE", redStatus + center); p.setProperty("SYSTEMSTAT", s.substring(2)); } else if (s.startsWith("Y:")) { p.setProperty("STATSTYLE", yellowStatus + center); p.setProperty("SYSTEMSTAT", s.substring(2)); } else { p.setProperty("STATSTYLE", center); p.setProperty("SYSTEMSTAT", s); } String expHeader = EnvExpander.expand(header,p,new Date(status.lss.lrgsTime * 1000L)); xos.writeLiteral(expHeader); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy