1380 lines
54 KiB
C++
1380 lines
54 KiB
C++
//
|
|
// MODULE: STATUSPAGES.CPP
|
|
//
|
|
//
|
|
// PROJECT: Generic Troubleshooter DLL for Microsoft AnswerPoint
|
|
//
|
|
// COMPANY: Saltmine Creative, Inc. (206)-284-7511 support@saltmine.com
|
|
//
|
|
// AUTHOR: Oleg Kalosha
|
|
//
|
|
// ORIGINAL DATE: 10-23-98
|
|
//
|
|
// NOTES:
|
|
//
|
|
// Version Date By Comments
|
|
//--------------------------------------------------------------------
|
|
// V3.0 10-23-98 OK Created by division of apgtsctx.cpp
|
|
//
|
|
|
|
#pragma warning(disable:4786)
|
|
|
|
#include "stdafx.h"
|
|
#include "time.h"
|
|
#include "apgtscls.h"
|
|
#include "apgtscfg.h"
|
|
#include "CounterMgr.h"
|
|
#include "SafeTime.h"
|
|
#include "apgtsmfc.h"
|
|
|
|
//Global Declaration.
|
|
const CString k_strTableBorderColor = _T("\"#000000\"");
|
|
const CString k_strBGColorOfTitle = _T( "\"#333366\"");
|
|
const CString k_strTextColorOfTitleOrSubTitle = _T("\"#FFFFFF\"");
|
|
const CString k_strTextColorOfName = _T("\"#CCCCC99\"");
|
|
const CString k_strTextColorOfValue = _T("\"#FFFFCC\"");
|
|
const CString k_strBGColorOfSubTitle = _T("\"#3333CC\"");
|
|
|
|
void AppendNameAndValueAsRow(CString &strAppend, CString strText, CString strVal)
|
|
{
|
|
strAppend += _T("<TR>\n");
|
|
if(strText != _T(""))
|
|
{
|
|
strAppend += _T("<TD BGCOLOR=");
|
|
strAppend += k_strTextColorOfName;
|
|
strAppend += _T(">");
|
|
strAppend += _T("<B>");
|
|
strAppend += strText;
|
|
strAppend += _T("</B>\n");
|
|
strAppend += _T("</TD>\n");
|
|
}
|
|
strAppend += _T("<TD ALIGN=\"CENTER\" BGCOLOR=");
|
|
strAppend += k_strTextColorOfValue;
|
|
strAppend += _T(">");
|
|
strAppend += strVal;
|
|
strAppend += _T("</TD>\n");
|
|
strAppend += _T("</TR>\n");
|
|
}
|
|
|
|
// If bSubTitle is TRUE, the subtitle inside the table will be displayed in a
|
|
// lighter background to differentiate between the title(darker background)
|
|
// and the subtitle.
|
|
|
|
void DisplayTextAsTable(CString &strDisplay, CString strText, bool bSubTitle)
|
|
{
|
|
strDisplay += _T("<TABLE BORDER= \"1\" BORDERCOLOR=");
|
|
strDisplay += k_strTableBorderColor;
|
|
strDisplay += _T("CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
strDisplay += _T("<TR>\n");
|
|
strDisplay += _T("<TD COLSPAN =2 ALIGN=\"CENTER\" BGCOLOR=");
|
|
if(bSubTitle)
|
|
strDisplay += k_strBGColorOfTitle;
|
|
else
|
|
strDisplay += k_strBGColorOfSubTitle;
|
|
strDisplay += _T(">\n");
|
|
strDisplay += _T("<FONT SIZE=\"+1\" COLOR=");
|
|
strDisplay += k_strTextColorOfTitleOrSubTitle;
|
|
strDisplay += _T("<B>\n");
|
|
strDisplay += strText;
|
|
strDisplay += _T("</B>\n");
|
|
strDisplay += _T("</TD>\n");
|
|
strDisplay += _T("</TR>\n");
|
|
}
|
|
|
|
void AppendTwoNamesAndValueAsRow(CString &strAppend, CString strText1, CString strText2, CString strVal)
|
|
{
|
|
strAppend += _T("<TR>\n");
|
|
strAppend += _T("<TD ALIGN=\"LEFT\" BGCOLOR=");
|
|
strAppend += k_strTextColorOfName;
|
|
strAppend += _T(" >");
|
|
strAppend += _T("<B>\n");
|
|
strAppend += strText1;
|
|
strAppend += _T("</B>\n");
|
|
strAppend += _T("</TD>");
|
|
strAppend += _T("<TD ALIGN=\"CENTER\" BGCOLOR=");
|
|
strAppend += k_strTextColorOfValue;
|
|
strAppend += _T(">\n");
|
|
strAppend += strText2;
|
|
strAppend += _T("</TD>\n");
|
|
strAppend += _T("<TD ALIGN=\"CENTER\" BGCOLOR=");
|
|
strAppend += k_strTextColorOfValue;
|
|
strAppend += _T(">\n");
|
|
strAppend += strVal;
|
|
strAppend += _T("</TD>\n");
|
|
strAppend += _T("</TR>\n");
|
|
}
|
|
|
|
|
|
// Returns true if we should show the full (rather than partial) first page.
|
|
bool APGTSContext::ShowFullFirstPage(bool bHasPwd)
|
|
{
|
|
// You can compile with the NOPWD option to suppress all password checking.
|
|
// This is intended mainly for creating test versions with this feature suppressed.
|
|
#ifdef NOPWD
|
|
return true;
|
|
#else
|
|
return bHasPwd;
|
|
#endif // ifndef NOPWD
|
|
}
|
|
|
|
void APGTSContext::InsertPasswordInForm()
|
|
{
|
|
// You can compile with the NOPWD option to suppress all password checking.
|
|
// This is intended mainly for creating test versions with this feature suppressed.
|
|
#ifndef NOPWD
|
|
m_strText += _T("<INPUT TYPE=hidden NAME=\"PWD\" VALUE=\"");
|
|
m_strText += m_strTempPwd;
|
|
m_strText += _T("\">\n");
|
|
#endif // ifndef NOPWD
|
|
}
|
|
|
|
void APGTSContext::BeginSelfAddressingForm()
|
|
{
|
|
m_strText += _T("<FORM ACTION=\"");
|
|
m_strText += _T("http://");
|
|
m_strText += m_strLocalIPAddress;
|
|
m_strText += m_strVRoot;
|
|
m_strText += _T("\" METHOD=POST>\n");
|
|
}
|
|
|
|
// Append to m_strText: contents of an HTML page giving:
|
|
// - usage statistics
|
|
// - list of available troubleshooter topics
|
|
// Not available to the end user.
|
|
// INPUT bHasPwd - if this is false, limit the info shown on this page.
|
|
void APGTSContext::DisplayFirstPage(bool bHasPwd)
|
|
{
|
|
CHourlyDailyCounter tmp_counter;
|
|
DWORD dwRegistryItem =0;
|
|
CString strRegistryItem;
|
|
const CString strRegistryItemNotFound = _T("not found");
|
|
|
|
CRegistryMonitor& registryMonitor = m_pConf->GetRegistryMonitor();
|
|
CThreadPool& threadPool = m_pConf->GetThreadPool();
|
|
CPoolQueue& poolQueue = m_pConf->GetPoolQueue();
|
|
|
|
m_strText += _T("<html>\n");
|
|
m_strText += _T("<B><head><title>Welcome</title></head>\n");
|
|
m_strText += _T("<body bgcolor=");
|
|
m_strText += k_strTextColorOfTitleOrSubTitle;
|
|
m_strText += _T(">\n");
|
|
m_strText += _T("<TABLE BORDER= \"1\" BORDERCOLOR=");
|
|
m_strText += k_strTableBorderColor;
|
|
m_strText += _T(" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
m_strText += _T("<TR>\n");
|
|
m_strText += _T("<TD COLSPAN=\"4\" ALIGN=CENTER BGCOLOR=");
|
|
m_strText += k_strBGColorOfTitle;
|
|
m_strText += _T(">\n");
|
|
m_strText += _T("<FONT SIZE=\"+3\" COLOR=");
|
|
m_strText += k_strTextColorOfTitleOrSubTitle;
|
|
m_strText += _T(">\n");
|
|
m_strText += _T("<B>Welcome To The Generic Troubleshooter v");
|
|
m_strText += gstrProductVersion;
|
|
m_strText += _T("</B></FONT> ");
|
|
m_strText += _T("</TD>\n");
|
|
m_strText += _T("</TR>\n");
|
|
|
|
m_strText += _T("</h1></center>\n");
|
|
m_strText += _T("</TABLE>\n");
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
// Display global counters
|
|
CString strTmp;
|
|
CHourlyDailyCounter* curr_counter = NULL;
|
|
m_strText += _T("<TABLE BORDER= \"1\" BORDERCOLOR=");
|
|
m_strText += k_strTableBorderColor;
|
|
m_strText += _T(" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdProgramContemporary));
|
|
if (curr_counter)
|
|
{
|
|
|
|
strTmp= CDisplayCounterCurrentDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Current Date/Time:"), strTmp);
|
|
|
|
strTmp = CDisplayCounterCreateDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/Time program started:"), strTmp);
|
|
|
|
}
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdStatusAccess));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterTotal(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Number of status accesses to system since program was started:"), strTmp);
|
|
|
|
strTmp = CDisplayCounterLastDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/Time of most recent status access:"), strTmp);
|
|
|
|
}
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdActionAccess));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterTotal(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Number of operator action accesses to system since program was started:"), strTmp);
|
|
|
|
strTmp = CDisplayCounterLastDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/Time of most recent operator action access:"), strTmp);
|
|
|
|
}
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdTotalAccessStart));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterTotal(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Number of total accesses to system since program was started:"), strTmp);
|
|
|
|
strTmp = CDisplayCounterLastDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/Time of most recent access:"), strTmp);
|
|
}
|
|
|
|
if (ShowFullFirstPage(bHasPwd))
|
|
{
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdRequestUnknown));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterTotal(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Number of requests to system for unknown troubleshooters topics since program was started:"), strTmp);
|
|
|
|
strTmp = CDisplayCounterLastDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/Time of most recent request to system for unknown troubleshooter topic:"), strTmp);
|
|
}
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdRequestRejected));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterTotal(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Number of requests system has rejected because of backlog in queue since program was started:"), strTmp);
|
|
|
|
strTmp = CDisplayCounterLastDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/Time of most recent request system has rejected because of backlog in queue:"), strTmp);
|
|
}
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdErrorLogged));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterTotal(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Number of errors logged to event log since program was started:"), strTmp);
|
|
|
|
strTmp = CDisplayCounterLastDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/Time of most recent logged error:"), strTmp);
|
|
}
|
|
|
|
|
|
if (registryMonitor.GetNumericInfo(CAPGTSRegConnector::eMaxWQItems, dwRegistryItem))
|
|
{
|
|
strRegistryItem.Format(_T("%d"), dwRegistryItem);
|
|
AppendNameAndValueAsRow(m_strText, _T("Current maximum size of queue:"), strRegistryItem);
|
|
}
|
|
else
|
|
AppendNameAndValueAsRow(m_strText, _T("Current maximum size of queue:"), strRegistryItemNotFound);
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
// Extract and display information about threads and queue
|
|
tmp_counter.Init(threadPool.GetWorkingThreadCount());
|
|
strTmp = CDisplayCounterTotal(&tmp_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Current number of working threads:"), strTmp);
|
|
|
|
tmp_counter.Init(poolQueue.GetTotalQueueItems());
|
|
strTmp = CDisplayCounterTotal(&tmp_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Current number of work items in queue:"), strTmp);
|
|
|
|
tmp_counter.Init(poolQueue.GetTotalWorkItems());
|
|
strTmp = CDisplayCounterTotal(&tmp_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Current number of work items either in queue or in progress:"), strTmp);
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
// Extract and display snapshot information about topic
|
|
DWORD dwTotal=0, dwNoInit=0, dwFail=0;
|
|
vector<CString> vector_placeholder;
|
|
m_pConf->GetTopicShop().GetTopicsStatus(dwTotal, dwNoInit, dwFail, &vector_placeholder);
|
|
tmp_counter.Init(dwTotal);
|
|
strTmp = CDisplayCounterTotal(&tmp_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Total number of known troubleshooter topics:"), strTmp);
|
|
|
|
if (ShowFullFirstPage(bHasPwd))
|
|
{
|
|
tmp_counter.Init(dwFail);
|
|
strTmp = CDisplayCounterTotal(&tmp_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Number of troubleshooter topics that we have tried and failed to load:"), strTmp);
|
|
}
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
m_strText += _T("</ul><center>\n");
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
// Display buttons to get to sibling status pages
|
|
if (ShowFullFirstPage(bHasPwd))
|
|
{
|
|
BeginSelfAddressingForm();
|
|
InsertPasswordInForm();
|
|
m_strText += _T("<INPUT TYPE=hidden NAME=\"");
|
|
m_strText += C_FURTHER_GLOBAL;
|
|
// Value here is not actually relevant; effectively used as a comment.
|
|
m_strText += _T("\" VALUE=\"Further Global Status Page\">\n");
|
|
m_strText += _T("<INPUT TYPE=SUBMIT VALUE=\"Further Global Status Page\">\n");
|
|
m_strText += _T("</FORM>\n");
|
|
|
|
BeginSelfAddressingForm();
|
|
InsertPasswordInForm();
|
|
m_strText += _T("<INPUT TYPE=hidden NAME=\"");
|
|
m_strText += C_THREAD_OVERVIEW;
|
|
// Value here is not actually relevant; effectively used as a comment.
|
|
m_strText += _T("\" VALUE=\"Thread Status Overview Page\">\n");
|
|
m_strText += _T("<INPUT TYPE=SUBMIT VALUE=\"Thread Status Overview Page\">\n");
|
|
m_strText += _T("</FORM>\n");
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
// Display topics & links to status information for those topics
|
|
vector<CString>arrstrTopic;
|
|
m_pConf->GetListOfTopicNames(arrstrTopic);
|
|
|
|
DWORD nTopics = arrstrTopic.size();
|
|
|
|
for (DWORD i=0; i<nTopics; i++)
|
|
{
|
|
m_strText += _T("<TABLE>");
|
|
m_strText += _T("<TR>");
|
|
m_strText += _T("<TD>");
|
|
|
|
BeginSelfAddressingForm();
|
|
m_strText += _T("<INPUT TYPE=hidden NAME=\"");
|
|
m_strText += C_TOPIC;
|
|
m_strText += _T("\" VALUE=\"");
|
|
m_strText += arrstrTopic[i];
|
|
m_strText += _T("\">\n");
|
|
m_strText += _T("<INPUT TYPE=SUBMIT VALUE=\"");
|
|
m_strText += _T("Problem Page for ");
|
|
m_strText += arrstrTopic[i];
|
|
m_strText += _T("\">\n");
|
|
m_strText += _T("</FORM>\n");
|
|
|
|
m_strText += _T("</TD>");
|
|
|
|
if (ShowFullFirstPage(bHasPwd))
|
|
{
|
|
m_strText += _T("<TD>");
|
|
|
|
BeginSelfAddressingForm();
|
|
InsertPasswordInForm();
|
|
m_strText += _T("<INPUT TYPE=hidden NAME=\"");
|
|
m_strText += C_TOPIC_STATUS;
|
|
m_strText += _T("\" VALUE=\"");
|
|
m_strText += arrstrTopic[i];
|
|
m_strText += _T("\">\n");
|
|
m_strText += _T("<INPUT TYPE=SUBMIT VALUE=\"");
|
|
m_strText += _T("Status Page for ");
|
|
m_strText += arrstrTopic[i];
|
|
m_strText += _T("\">\n");
|
|
m_strText += _T("</FORM>\n");
|
|
|
|
m_strText += _T("</TD>");
|
|
}
|
|
m_strText += _T("</TR>");
|
|
m_strText += _T("</TABLE>");
|
|
}
|
|
if(nTopics == 0)
|
|
{
|
|
m_strText += _T("<P>There are currently no troubleshooters available");
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
m_strText += _T("</center>\n");
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
if (ShowFullFirstPage(bHasPwd))
|
|
{
|
|
m_strText += _T("<TABLE BORDER= \"1\" BORDERCOLOR=\"#000000\" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
// Display registry info
|
|
|
|
if (registryMonitor.GetStringInfo(CAPGTSRegConnector::eResourcePath, strRegistryItem))
|
|
AppendNameAndValueAsRow(m_strText, _T("Full path to resource:"), strRegistryItem);
|
|
else
|
|
AppendNameAndValueAsRow(m_strText, _T("Full path to resource:"), strRegistryItemNotFound);
|
|
|
|
|
|
if (registryMonitor.GetNumericInfo(CAPGTSRegConnector::eCookieLife, dwRegistryItem))
|
|
{
|
|
strRegistryItem.Format(_T("%d"), dwRegistryItem);
|
|
AppendNameAndValueAsRow(m_strText, _T("HTTP cookie expiration in minutes:"), strRegistryItem);
|
|
}
|
|
else
|
|
AppendNameAndValueAsRow(m_strText, _T("HTTP cookie expiration in minutes:"), strRegistryItemNotFound);
|
|
|
|
|
|
if (registryMonitor.GetNumericInfo(CAPGTSRegConnector::eMaxThreads, dwRegistryItem))
|
|
{
|
|
|
|
strRegistryItem.Format(_T("%d"), dwRegistryItem);
|
|
AppendNameAndValueAsRow(m_strText, _T("Maximum threads:"), strRegistryItem);
|
|
}
|
|
else
|
|
AppendNameAndValueAsRow(m_strText, _T("Maximum threads:"), strRegistryItemNotFound);
|
|
|
|
|
|
if (registryMonitor.GetNumericInfo(CAPGTSRegConnector::eMaxWQItems, dwRegistryItem))
|
|
{
|
|
strRegistryItem.Format(_T("%d"), dwRegistryItem);
|
|
AppendNameAndValueAsRow(m_strText, _T("Maximum work queue items:"), strRegistryItem);
|
|
}
|
|
else
|
|
AppendNameAndValueAsRow(m_strText, _T("Maximum work queue items :"), strRegistryItemNotFound);
|
|
|
|
|
|
if (registryMonitor.GetNumericInfo(CAPGTSRegConnector::eReloadDelay, dwRegistryItem))
|
|
{
|
|
strRegistryItem.Format(_T("%d"), dwRegistryItem);
|
|
AppendNameAndValueAsRow(m_strText, _T("Refresh delay:"), strRegistryItem);
|
|
}
|
|
else
|
|
AppendNameAndValueAsRow(m_strText, _T("Refresh delay:"), strRegistryItemNotFound);
|
|
|
|
|
|
if (registryMonitor.GetNumericInfo(CAPGTSRegConnector::eThreadsPP, dwRegistryItem))
|
|
{
|
|
strRegistryItem.Format(_T("%d"), dwRegistryItem);
|
|
AppendNameAndValueAsRow(m_strText, _T("Threads per processor:"), strRegistryItem);
|
|
}
|
|
else
|
|
AppendNameAndValueAsRow(m_strText, _T("Threads per processor:"), strRegistryItemNotFound);
|
|
|
|
|
|
if (registryMonitor.GetStringInfo(CAPGTSRegConnector::eVrootPath, strRegistryItem))
|
|
AppendNameAndValueAsRow(m_strText, _T("VRoot path to DLL:"), strRegistryItem);
|
|
else
|
|
AppendNameAndValueAsRow(m_strText, _T("VRoot path to DLL:"), strRegistryItemNotFound);
|
|
|
|
if (registryMonitor.GetNumericInfo(CAPGTSRegConnector::eDetailedEventLogging, dwRegistryItem))
|
|
{
|
|
strRegistryItem.Format(_T("%d"), dwRegistryItem);
|
|
AppendNameAndValueAsRow(m_strText, _T("Detailed event logging:"), strRegistryItem);
|
|
}
|
|
else
|
|
AppendNameAndValueAsRow(m_strText, _T("Detailed event logging:"), strRegistryItemNotFound);
|
|
|
|
if (registryMonitor.GetStringInfo(CAPGTSRegConnector::eLogFilePath, strRegistryItem))
|
|
AppendNameAndValueAsRow(m_strText, _T("Log file directory:"), strRegistryItem);
|
|
else
|
|
AppendNameAndValueAsRow(m_strText, _T("Log file directory:"), strRegistryItemNotFound);
|
|
|
|
}
|
|
m_strText += _T("</TABLE>\n");
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
m_strText += _T("</body></html>\n");
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
}
|
|
|
|
void APGTSContext::DisplayFurtherGlobalStatusPage()
|
|
{
|
|
|
|
CHourlyDailyCounter tmp_counter;
|
|
DWORD dwRegistryItem =0;
|
|
CString strRegistryItem;
|
|
CString strTmp;
|
|
const CString strRegistryItemNotFound = _T("not found");
|
|
CRegistryMonitor& registryMonitor = m_pConf->GetRegistryMonitor();
|
|
CThreadPool& threadPool = m_pConf->GetThreadPool();
|
|
CPoolQueue& poolQueue = m_pConf->GetPoolQueue();
|
|
CHourlyDailyCounter* curr_counter = NULL;
|
|
CDailyTotals daily;
|
|
CHourlyTotals hourly;
|
|
|
|
m_strText += _T("<html>\n");
|
|
m_strText += _T("<B><head><title>Status</title></head>\n");
|
|
m_strText += _T("<body bgcolor=");
|
|
m_strText += k_strTextColorOfTitleOrSubTitle;
|
|
m_strText += _T(">\n");
|
|
m_strText += _T("<TABLE BORDER= \"1\" BORDERCOLOR=");
|
|
m_strText += k_strTableBorderColor;
|
|
m_strText += _T(" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
m_strText += _T("<TR>\n");
|
|
m_strText += _T("<TD COLSPAN=\"4\" ALIGN=CENTER BGCOLOR=");
|
|
m_strText += k_strBGColorOfTitle;
|
|
m_strText += _T(">\n");
|
|
m_strText += _T("<FONT SIZE=\"+3\" COLOR=");
|
|
m_strText += k_strTextColorOfTitleOrSubTitle;
|
|
m_strText += _T(">\n");
|
|
m_strText += _T("<B>Further Global Status Page ");
|
|
m_strText += _T("</B></FONT> ");
|
|
m_strText += _T("</TD>\n");
|
|
m_strText += _T("</TR>\n");
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
// Display global counters
|
|
|
|
m_strText += _T("<TABLE BORDER=\"1\" BORDERCOLOR=");
|
|
m_strText += k_strTableBorderColor;
|
|
m_strText += _T(" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdProgramContemporary));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterCurrentDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Current Date/Time:"), strTmp);
|
|
}
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<br>\n");
|
|
|
|
DisplayTextAsTable(m_strText, _T("Status Access To The System"), 1);
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdStatusAccess));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterTotal(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Number of status accesses to system since program was started:"), strTmp);
|
|
|
|
strTmp = CDisplayCounterLastDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/Time of most recent status access:"), strTmp);
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
DisplayTextAsTable(m_strText, _T("Daily/hourly count of status accesses to system since program was started"), 0);
|
|
m_strText += CDisplayCounterDailyHourly(curr_counter, &daily, &hourly).Display();
|
|
|
|
}
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<br>\n");
|
|
|
|
DisplayTextAsTable(m_strText, _T("Operator Access To The System"), 1);
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<TABLE BORDER=\"1\" BORDERCOLOR=");
|
|
m_strText += k_strTableBorderColor;
|
|
m_strText += _T(" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdActionAccess));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterTotal(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Number of operator action accesses to system since program was started:"), strTmp);
|
|
|
|
strTmp = CDisplayCounterLastDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/Time of most recent operator action access:"), strTmp);
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
DisplayTextAsTable(m_strText, _T("Daily/hourly count of operator action accesses to system since program was started"), 0);
|
|
m_strText += CDisplayCounterDailyHourly(curr_counter, &daily, &hourly).Display();
|
|
|
|
}
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<br>\n");
|
|
|
|
DisplayTextAsTable(m_strText, _T("Total Access To The System"), 1);
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<TABLE BORDER=\"1\" BORDERCOLOR=");
|
|
m_strText += k_strTableBorderColor;
|
|
m_strText += _T(" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdTotalAccessStart));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterTotal(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Number of total accesses to system since program was started:"), strTmp);
|
|
|
|
strTmp = CDisplayCounterLastDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/Time of most recent access:"), strTmp);
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
DisplayTextAsTable(m_strText, _T("Daily/hourly count of total accesses to system since program was started"), 0);
|
|
m_strText += CDisplayCounterDailyHourly(curr_counter, &daily, &hourly).Display();
|
|
|
|
}
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<br>\n");
|
|
DisplayTextAsTable(m_strText, _T("Request To System For UnKnown TroubleShooter Topics"), 1);
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<TABLE BORDER=\"1\" BORDERCOLOR=");
|
|
m_strText += k_strTableBorderColor;
|
|
m_strText += _T(" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdRequestUnknown));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterTotal(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Number of requests to system for unknown troubleshooters topics since program was started:"), strTmp);
|
|
|
|
strTmp = CDisplayCounterLastDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/Time of most recent request to system for unknown troubleshooter topic:"), strTmp);
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
DisplayTextAsTable(m_strText, _T("Daily/hourly count of requests to system for unknown troubleshooter topics since program was started"), 0);
|
|
m_strText += CDisplayCounterDailyHourly(curr_counter, &daily, &hourly).Display();
|
|
|
|
}
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<br>\n");
|
|
|
|
DisplayTextAsTable(m_strText, _T("Requests System Has Rejected"), 1);
|
|
m_strText += _T("</TABLE>\n");
|
|
|
|
m_strText += _T("<TABLE BORDER=\"1\" BORDERCOLOR=");
|
|
m_strText += k_strTableBorderColor;
|
|
m_strText += _T(" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdRequestRejected));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterTotal(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Number of requests system has rejected because of backlog in queue since program was started:"), strTmp);
|
|
|
|
strTmp = CDisplayCounterLastDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/Time of most recent request system has rejected because of backlog in queue:"), strTmp);
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
DisplayTextAsTable(m_strText, _T("Daily/hourly count of requests system has rejected because of backlog in queue since program was started"), 0);
|
|
m_strText += CDisplayCounterDailyHourly(curr_counter, &daily, &hourly).Display();
|
|
|
|
}
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<br>\n");
|
|
DisplayTextAsTable(m_strText, _T("Errors Logged To Event Log"), 1);
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<TABLE BORDER=\"1\" BORDERCOLOR=");
|
|
m_strText += k_strTableBorderColor;
|
|
m_strText += _T(" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdErrorLogged));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterTotal(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Number of errors logged to event log since program was started:"), strTmp);
|
|
|
|
strTmp = CDisplayCounterLastDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/Time of most recent logged error:"), strTmp);
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
DisplayTextAsTable(m_strText, _T("Daily/hourly count of logged errors"), 0);
|
|
m_strText += CDisplayCounterDailyHourly(curr_counter, &daily, &hourly).Display();
|
|
}
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<br>\n");
|
|
|
|
DisplayTextAsTable(m_strText, _T("Statistics About Queue, Thread and Successful/Unsuccessful Load Of Topics"), 1);
|
|
m_strText += _T("</TABLE>\n");
|
|
|
|
m_strText += _T("<TABLE BORDER=\"1\" BORDERCOLOR=");
|
|
m_strText += k_strTableBorderColor;
|
|
m_strText += _T(" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
|
|
if (registryMonitor.GetNumericInfo(CAPGTSRegConnector::eMaxWQItems, dwRegistryItem))
|
|
{
|
|
strRegistryItem.Format(_T("%d"), dwRegistryItem);
|
|
AppendNameAndValueAsRow(m_strText, _T("Current maximum size of queue:"), strRegistryItem);
|
|
}
|
|
else
|
|
AppendNameAndValueAsRow(m_strText, _T("Current maximum size of queue:"), strRegistryItemNotFound);
|
|
m_strText += _T("\n");
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
// Extract and display information about threads and queue
|
|
|
|
|
|
tmp_counter.Init(threadPool.GetWorkingThreadCount());
|
|
strTmp = CDisplayCounterTotal(&tmp_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Current number of working threads:"), strTmp);
|
|
|
|
tmp_counter.Init(poolQueue.GetTotalQueueItems());
|
|
strTmp = CDisplayCounterTotal(&tmp_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Current number of work items in queue :"), strTmp);
|
|
|
|
tmp_counter.Init(poolQueue.GetTotalWorkItems());
|
|
strTmp = CDisplayCounterTotal(&tmp_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Current number of work items either in queue or in progress :"), strTmp);
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
|
|
strTmp = CSafeTime(poolQueue.GetTimeLastAdd()).StrLocalTime();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/Time of most recent addition to queue :"), strTmp);
|
|
|
|
strTmp = CSafeTime(poolQueue.GetTimeLastRemove()).StrLocalTime();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/Time of most recent removal from queue :"), strTmp);
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
// Extract and display snapshot information about topic
|
|
DWORD dwTotal=0, dwNoInit=0, dwFail=0;
|
|
vector<CString> vector_topics_failed;
|
|
m_pConf->GetTopicShop().GetTopicsStatus(dwTotal, dwNoInit, dwFail, &vector_topics_failed);
|
|
tmp_counter.Init(dwTotal);
|
|
strTmp = CDisplayCounterTotal(&tmp_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Total number of known troubleshooter topics:"), strTmp);
|
|
|
|
tmp_counter.Init(dwNoInit);
|
|
strTmp = CDisplayCounterTotal(&tmp_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Number of troubleshooter topics that we have not yet tried to load:"), strTmp);
|
|
|
|
tmp_counter.Init(dwFail);
|
|
strTmp = CDisplayCounterTotal(&tmp_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Number of troubleshooter topics that we have tried and failed to load:"), strTmp);
|
|
|
|
if (vector_topics_failed.size())
|
|
for (vector<CString>::iterator i = vector_topics_failed.begin(); i != vector_topics_failed.end(); i++)
|
|
{
|
|
strTmp = *i;
|
|
AppendNameAndValueAsRow(m_strText, _T("List of troubleshooter topics that we have tried and failed to load:"), strTmp);
|
|
}
|
|
else
|
|
{
|
|
strTmp = _T("No topics");
|
|
AppendNameAndValueAsRow(m_strText, _T("List of troubleshooter topics that we have tried and failed to load:"), strTmp);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
// Extract and display snapshot information about alternate templates
|
|
vector<CString> vector_templates_failed;
|
|
vector<DWORD> vector_templatescnt_failed;
|
|
DWORD dwTemplateCnt;
|
|
m_pConf->GetTopicShop().GetTemplatesStatus( &vector_templates_failed, &vector_templatescnt_failed );
|
|
dwTemplateCnt= vector_templates_failed.size();
|
|
if (dwTemplateCnt)
|
|
{
|
|
// Only output if there are failed loads.
|
|
tmp_counter.Init( dwTemplateCnt );
|
|
strTmp = CDisplayCounterTotal(&tmp_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Total number of templates not found:"), strTmp);
|
|
|
|
vector<DWORD>::iterator j = vector_templatescnt_failed.begin();
|
|
for (vector<CString>::iterator i = vector_templates_failed.begin();
|
|
i != vector_templates_failed.end(); i++)
|
|
{
|
|
strTmp = *i;
|
|
AppendNameAndValueAsRow(m_strText, _T(""), strTmp);
|
|
|
|
if (j != vector_templatescnt_failed.end())
|
|
{
|
|
// Output the counts.
|
|
tmp_counter.Init( *j );
|
|
strTmp = CDisplayCounterTotal(&tmp_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T(": "), strTmp);
|
|
j++;
|
|
}
|
|
}
|
|
}
|
|
m_strText += _T("</TABLE>\n");
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
// Link buttons
|
|
BeginSelfAddressingForm();
|
|
InsertPasswordInForm();
|
|
m_strText += _T("<INPUT TYPE=hidden NAME=\"");
|
|
m_strText += C_FIRST;
|
|
// Value here is not actually relevant; effectively used as a comment.
|
|
m_strText += _T("\" VALUE=\"Front Page\">\n");
|
|
m_strText += _T("<INPUT TYPE=SUBMIT VALUE=\"Front Page\">\n");
|
|
m_strText += _T("</FORM>\n");
|
|
|
|
BeginSelfAddressingForm();
|
|
InsertPasswordInForm();
|
|
m_strText += _T("<INPUT TYPE=hidden NAME=\"");
|
|
m_strText += C_THREAD_OVERVIEW;
|
|
// Value here is not actually relevant; effectively used as a comment.
|
|
m_strText += _T("\" VALUE=\"Thread Status Overview Page\">\n");
|
|
m_strText += _T("<INPUT TYPE=SUBMIT VALUE=\"Thread Status Overview Page\">\n");
|
|
m_strText += _T("</FORM>\n");
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
m_strText += _T("</body></html>\n");
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
}
|
|
|
|
void APGTSContext::DisplayThreadStatusOverviewPage()
|
|
{
|
|
CString strTmp;
|
|
CString strTmp2;
|
|
CString strTmp3;
|
|
CString strTmp4;
|
|
CHourlyDailyCounter tmp_counter;
|
|
DWORD dwRegistryItem =0;
|
|
CString strRegistryItem;
|
|
const CString strRegistryItemNotFound = _T("not found");
|
|
CRegistryMonitor& registryMonitor = m_pConf->GetRegistryMonitor();
|
|
CDirectoryMonitor& directoryMonitor = m_pConf->GetDirectoryMonitor();
|
|
CTopicShop& topicShop = m_pConf->GetTopicShop();
|
|
CThreadPool& threadPool = m_pConf->GetThreadPool();
|
|
CPoolQueue& poolQueue = m_pConf->GetPoolQueue();
|
|
CHourlyDailyCounter* curr_counter = NULL;
|
|
CDailyTotals daily;
|
|
CHourlyTotals hourly;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
// Collect status information for pool threads
|
|
vector<CPoolThreadStatus> arrPoolThreadStatus;
|
|
for (long i = 0; i < threadPool.GetWorkingThreadCount(); i++)
|
|
{
|
|
CPoolThreadStatus status;
|
|
threadPool.ThreadStatus(i, status);
|
|
arrPoolThreadStatus.push_back(status);
|
|
}
|
|
|
|
|
|
m_strText += _T("<html>\n");
|
|
m_strText += _T("<B><head><title>Status</title></head>\n");
|
|
m_strText += _T("<body bgcolor=");
|
|
m_strText += k_strTextColorOfTitleOrSubTitle;
|
|
m_strText += _T(">\n");
|
|
m_strText += _T("<TABLE BORDER=\"1\" BORDERCOLOR=");
|
|
m_strText += k_strTableBorderColor;
|
|
m_strText += _T(" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
m_strText += _T("<TR>\n");
|
|
m_strText += _T("<TD COLSPAN=\"4\" ALIGN=CENTER BGCOLOR=");
|
|
m_strText += k_strBGColorOfTitle;
|
|
m_strText += _T(">\n");
|
|
m_strText += _T("<FONT SIZE=\"+3\" COLOR=");
|
|
m_strText += k_strTextColorOfTitleOrSubTitle;
|
|
m_strText += _T(">\n");
|
|
m_strText += _T("<B>Thread Status Overview Page ");
|
|
m_strText += _T("</B></FONT> ");
|
|
m_strText += _T("</TD>\n");
|
|
m_strText += _T("</TR>\n");
|
|
m_strText += _T("</h1></center>\n");
|
|
m_strText += _T("</TABLE>\n");
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
// Display global counters
|
|
m_strText += _T("<TABLE BORDER=\"1\" BORDERCOLOR=\"#000000\" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdProgramContemporary));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterCurrentDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Current Date/Time:"), strTmp);
|
|
}
|
|
|
|
|
|
if (registryMonitor.GetNumericInfo(CAPGTSRegConnector::eMaxWQItems, dwRegistryItem))
|
|
{
|
|
strRegistryItem.Format(_T("%d"), dwRegistryItem);
|
|
AppendNameAndValueAsRow(m_strText, _T("Current maximum size of queue:"), strRegistryItem);
|
|
}
|
|
else
|
|
AppendNameAndValueAsRow(m_strText, _T("Current maximum size of queue:"), strRegistryItemNotFound);
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
// Extract and display information about threads and queue
|
|
tmp_counter.Init(threadPool.GetWorkingThreadCount());
|
|
strTmp = CDisplayCounterTotal(&tmp_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Current number of working threads:"), strTmp);
|
|
|
|
tmp_counter.Init(poolQueue.GetTotalQueueItems());
|
|
strTmp = CDisplayCounterTotal(&tmp_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Current number of work items in queue:"), strTmp);
|
|
|
|
tmp_counter.Init(poolQueue.GetTotalWorkItems());
|
|
strTmp = CDisplayCounterTotal(&tmp_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Current number of work items either in queue or in progress:"), strTmp);
|
|
|
|
strTmp = CSafeTime(poolQueue.GetTimeLastAdd()).StrLocalTime();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/Time of most recent addition to queue:"), strTmp);
|
|
|
|
strTmp = CSafeTime(poolQueue.GetTimeLastRemove()).StrLocalTime();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/Time of most recent removal from queue:"), strTmp);
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
// thread pool status information
|
|
long more5 = 0, more10 = 0;
|
|
vector<CPoolThreadStatus> arrPoolThreadStatusOlder5;
|
|
// This next is slightly klugy. Ideally, we'd get this info into arrPoolThreadStatusOlder5
|
|
vector<DWORD> Older5ThreadNumber;
|
|
for (i = 0; i < arrPoolThreadStatus.size(); i++)
|
|
{
|
|
if (arrPoolThreadStatus[i].m_bWorking)
|
|
{
|
|
if (arrPoolThreadStatus[i].m_seconds > 5)
|
|
{
|
|
arrPoolThreadStatusOlder5.push_back(arrPoolThreadStatus[i]);
|
|
Older5ThreadNumber.push_back(i);
|
|
more5++;
|
|
}
|
|
if (arrPoolThreadStatus[i].m_seconds > 10)
|
|
more10++;
|
|
}
|
|
}
|
|
|
|
|
|
strTmp.Format(_T("%ld"), more5);
|
|
AppendNameAndValueAsRow(m_strText, _T("Number of pool threads that have been working on a task for more than 5 seconds:"), strTmp);
|
|
|
|
strTmp.Format(_T("%ld"), more10);
|
|
AppendNameAndValueAsRow(m_strText, _T("Number of pool threads that have been working on a task for more than 10 seconds:"), strTmp);
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<br>\n");
|
|
DisplayTextAsTable(m_strText, _T("Detailed information on each of the pool threads that has been working on a task for more than 5 seconds"), 1);
|
|
|
|
for (i = 0; i < arrPoolThreadStatusOlder5.size(); i++)
|
|
{
|
|
strTmp.Format(_T("<B>Thread %d </B>"), Older5ThreadNumber[i]);
|
|
strTmp2 = _T(" has been in \"working\" state for ");
|
|
strTmp += strTmp2;
|
|
strTmp3.Format(_T("%ld"), (long)arrPoolThreadStatusOlder5[i].m_seconds);
|
|
strTmp3 += _T(" seconds");
|
|
AppendNameAndValueAsRow(m_strText, strTmp, strTmp3);
|
|
|
|
strTmp.Format( _T("Date/Time thread %d started:"), Older5ThreadNumber[i]);
|
|
strTmp2 = CSafeTime(arrPoolThreadStatusOlder5[i].m_timeCreated).StrLocalTime();
|
|
AppendNameAndValueAsRow(m_strText, strTmp, strTmp2);
|
|
|
|
strTmp.Format( _T("Thread %d is working on topic:"), Older5ThreadNumber[i]);
|
|
strTmp2 = arrPoolThreadStatusOlder5[i].m_strTopic.GetLength()
|
|
? arrPoolThreadStatusOlder5[i].m_strTopic
|
|
: _T("no topic");
|
|
AppendNameAndValueAsRow(m_strText, strTmp, strTmp2);
|
|
|
|
|
|
strTmp.Format (_T("Client IP address for Thread %d:"),Older5ThreadNumber[i] );
|
|
strTmp2 = arrPoolThreadStatusOlder5[i].m_strClientIP.GetLength()
|
|
? arrPoolThreadStatusOlder5[i].m_strClientIP : _T("no address");
|
|
AppendNameAndValueAsRow(m_strText, strTmp, strTmp2);
|
|
|
|
|
|
strTmp.Format( _T(" Client browser for Thread %d:"), Older5ThreadNumber[i] );
|
|
strTmp2 = arrPoolThreadStatusOlder5[i].m_strBrowser.GetLength()
|
|
? arrPoolThreadStatusOlder5[i].m_strBrowser : _T("no browser");
|
|
|
|
AppendNameAndValueAsRow(m_strText, strTmp, strTmp2);
|
|
|
|
|
|
|
|
}
|
|
if (!i)
|
|
AppendNameAndValueAsRow(m_strText, _T(""), _T("No threads"));
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
// registry monitor thread status information
|
|
CRegistryMonitor::ThreadStatus registryStatus;
|
|
DWORD registrySeconds = 0;
|
|
CString strRegistryStatus;
|
|
registryMonitor.GetStatus(registryStatus, registrySeconds);
|
|
switch(registryStatus)
|
|
{
|
|
case CRegistryMonitor::eBeforeInit: strRegistryStatus = _T("Before Init");
|
|
break;
|
|
case CRegistryMonitor::eInit: strRegistryStatus = _T("Init");
|
|
break;
|
|
case CRegistryMonitor::eFail: strRegistryStatus = _T("Fail");
|
|
break;
|
|
case CRegistryMonitor::eDefaulting: strRegistryStatus = _T("Defaulting");
|
|
break;
|
|
case CRegistryMonitor::eWait: strRegistryStatus = _T("Wait");
|
|
break;
|
|
case CRegistryMonitor::eRun: strRegistryStatus = _T("Run");
|
|
break;
|
|
case CRegistryMonitor::eExiting: strRegistryStatus = _T("Exiting");
|
|
break;
|
|
}
|
|
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<br>\n");
|
|
m_strText += _T("<TABLE BORDER=\"1\" BORDERCOLOR=");
|
|
m_strText += k_strTableBorderColor;
|
|
m_strText += _T(" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
|
|
strTmp = strRegistryStatus;
|
|
AppendNameAndValueAsRow(m_strText, _T("Current status of Registry Monitor thread:"), strTmp);
|
|
|
|
strTmp.Format(_T("%ld"), (long)registrySeconds);
|
|
strTmp += _T(" seconds\n");
|
|
AppendNameAndValueAsRow(m_strText, _T("The thread has been in this status for "), strTmp);
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
// directory monitor thread status information
|
|
CDirectoryMonitor::ThreadStatus directoryStatus;
|
|
DWORD directorySeconds = 0;
|
|
CString strDirectoryStatus;
|
|
directoryMonitor.GetStatus(directoryStatus, directorySeconds);
|
|
switch(directoryStatus)
|
|
{
|
|
case CDirectoryMonitor::eBeforeInit: strDirectoryStatus = _T("Before Init");
|
|
break;
|
|
case CDirectoryMonitor::eFail: strDirectoryStatus = _T("Fail");
|
|
break;
|
|
case CDirectoryMonitor::eWaitDirPath: strDirectoryStatus = _T("Wait For Dir Path");
|
|
break;
|
|
case CDirectoryMonitor::eWaitChange: strDirectoryStatus = _T("Wait For Change");
|
|
break;
|
|
case CDirectoryMonitor::eWaitSettle: strDirectoryStatus = _T("Wait To Settle");
|
|
break;
|
|
case CDirectoryMonitor::eRun: strDirectoryStatus = _T("Run");
|
|
break;
|
|
case CDirectoryMonitor::eBeforeWaitChange: strDirectoryStatus = _T("Before Wait Change");
|
|
break;
|
|
case CDirectoryMonitor::eExiting: strDirectoryStatus = _T("Exiting");
|
|
break;
|
|
}
|
|
|
|
strTmp = strDirectoryStatus;
|
|
AppendNameAndValueAsRow(m_strText, _T("Current status of Directory Monitor thread:"), strTmp);
|
|
|
|
strTmp.Format(_T("%ld"), (long)directorySeconds);
|
|
strTmp += _T(" seconds\n");
|
|
AppendNameAndValueAsRow(m_strText, _T("The thread has been in this status for "), strTmp);
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
// topic builder thread status information
|
|
CTopicShop::ThreadStatus topicshopStatus;
|
|
DWORD topicshopSeconds = 0;
|
|
CString strTopicshopStatus;
|
|
topicShop.GetThreadStatus(topicshopStatus, topicshopSeconds);
|
|
switch(topicshopStatus)
|
|
{
|
|
case CTopicShop::eBeforeInit: strTopicshopStatus = _T("Before Init");
|
|
break;
|
|
case CTopicShop::eFail: strTopicshopStatus = _T("Fail");
|
|
break;
|
|
case CTopicShop::eWait: strTopicshopStatus = _T("Wait");
|
|
break;
|
|
case CTopicShop::eRun: strTopicshopStatus = _T("Run");
|
|
break;
|
|
case CTopicShop::eExiting: strTopicshopStatus = _T("Exiting");
|
|
break;
|
|
}
|
|
|
|
strTmp = strTopicshopStatus;
|
|
AppendNameAndValueAsRow(m_strText, _T("Current status of TopicShop Monitor thread:"), strTmp);
|
|
|
|
strTmp.Format(_T("%ld"), (long)topicshopSeconds);
|
|
strTmp += _T(" seconds\n");
|
|
AppendNameAndValueAsRow(m_strText, _T("The thread has been in this status for "), strTmp);
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<br>\n");
|
|
DisplayTextAsTable(m_strText, _T("State of each pool thread"), 1);
|
|
|
|
for (i = 0; i < arrPoolThreadStatus.size(); i++)
|
|
{
|
|
strTmp.Format(_T("<B>Thread %d has been in "), i);
|
|
strTmp2 = arrPoolThreadStatus[i].m_bWorking ? _T("\"working\"") : _T("\"waiting\"");
|
|
strTmp3 = _T(" state for </B>");
|
|
strTmp2 += strTmp3;
|
|
strTmp += strTmp2;
|
|
strTmp4.Format(_T("%ld"), (long)arrPoolThreadStatus[i].m_seconds);
|
|
strTmp4 += _T(" seconds.");
|
|
AppendNameAndValueAsRow(m_strText, strTmp, strTmp4);
|
|
}
|
|
if (!i)
|
|
AppendNameAndValueAsRow(m_strText, _T(""),_T("No threads") );
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
// Link buttons
|
|
BeginSelfAddressingForm();
|
|
InsertPasswordInForm();
|
|
m_strText += _T("<INPUT TYPE=hidden NAME=\"");
|
|
m_strText += C_FURTHER_GLOBAL;
|
|
// Value here is not actually relevant; effectively used as a comment.
|
|
m_strText += _T("\" VALUE=\"Further Global Status Page\">\n");
|
|
m_strText += _T("<INPUT TYPE=SUBMIT VALUE=\"Further Global Status Page\">\n");
|
|
m_strText += _T("</FORM>\n");
|
|
|
|
BeginSelfAddressingForm();
|
|
InsertPasswordInForm();
|
|
m_strText += _T("<INPUT TYPE=hidden NAME=\"");
|
|
m_strText += C_FIRST;
|
|
// Value here is not actually relevant; effectively used as a comment.
|
|
m_strText += _T("\" VALUE=\"Front Page\">\n");
|
|
m_strText += _T("<INPUT TYPE=SUBMIT VALUE=\"Front Page\">\n");
|
|
m_strText += _T("</FORM>\n");
|
|
|
|
m_strText += _T("</body></html>\n");
|
|
}
|
|
|
|
///////////////////////////
|
|
|
|
void APGTSContext::DisplayTopicStatusPage(LPCTSTR topic_name)
|
|
{
|
|
CHourlyDailyCounter tmp_counter, *curr_counter;
|
|
CTopicShop& topicShop = m_pConf->GetTopicShop();
|
|
CTopicInCatalog* pTopicInCatalog = topicShop.GetCatalogEntry(topic_name);
|
|
CHourlyTotals hourly;
|
|
CDailyTotals daily;
|
|
CString strTmp;
|
|
CString strTmp2;
|
|
|
|
m_strText += _T("<html>\n");
|
|
m_strText += _T("<B><head><title>Status</title></head>\n");
|
|
m_strText += _T("<body bgcolor=");
|
|
m_strText += k_strTextColorOfTitleOrSubTitle;
|
|
m_strText += _T(">\n");
|
|
m_strText += _T("<TABLE BORDER=\"1\" BORDERCOLOR=");
|
|
m_strText += k_strTableBorderColor;
|
|
m_strText += _T(" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
m_strText += _T("<TR>\n");
|
|
m_strText += _T("<TD COLSPAN=\"4\" ALIGN=CENTER BGCOLOR=");
|
|
m_strText += k_strBGColorOfTitle;
|
|
m_strText += _T("> \n");
|
|
m_strText += _T("<FONT SIZE=\"+3\" COLOR=");
|
|
m_strText += k_strTextColorOfTitleOrSubTitle;
|
|
m_strText += _T("> \n");
|
|
m_strText += _T("<B>Topic Status Page for ");
|
|
m_strText += topic_name;
|
|
m_strText += _T("</B></FONT> ");
|
|
m_strText += _T("</TD>\n");
|
|
m_strText += _T("</TR>\n");
|
|
|
|
|
|
if (pTopicInCatalog)
|
|
m_strText += _T("</h1></center>\n");
|
|
else
|
|
{
|
|
m_strText += _T("No data available");
|
|
m_strText += _T("</h1></center>\n");
|
|
return;
|
|
}
|
|
|
|
CTopicInfo topicInfo = pTopicInCatalog->GetTopicInfo();
|
|
CString strDsc = CAbstractFileReader::GetJustName(topicInfo.GetDscFilePath());
|
|
CString strHti = CAbstractFileReader::GetJustName(topicInfo.GetHtiFilePath());
|
|
CString strBes = CAbstractFileReader::GetJustName(topicInfo.GetBesFilePath());
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<TABLE BORDER= \"1\" BORDERCOLOR=\"#000000\" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdProgramContemporary));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterCurrentDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Current Date/Time:"), strTmp);
|
|
}
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
|
|
m_strText += _T("<TABLE BORDER=\"1\" BORDERCOLOR=");
|
|
m_strText += k_strTableBorderColor;
|
|
m_strText += _T(" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
|
|
strTmp = CString(_T("<BR>")) + (strDsc.GetLength() ? strDsc : _T("Unknown"));
|
|
strTmp2 = CString(_T("<BR>")) + topicInfo.GetStrDscFileCreated();
|
|
AppendTwoNamesAndValueAsRow(m_strText, _T("DSC file:"), strTmp, strTmp2);
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<TABLE BORDER=\"1\" BORDERCOLOR=");
|
|
m_strText += k_strTableBorderColor;
|
|
m_strText += _T(" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
|
|
bool bHTIinsideOfDSC= false, bBESinsideOfDSC= false;
|
|
{
|
|
CP_TOPIC ptrTopic;
|
|
pTopicInCatalog->GetTopicNoWait(ptrTopic);
|
|
|
|
CString strTmp;
|
|
if (!ptrTopic.IsNull())
|
|
{
|
|
strTmp = ptrTopic->GetNetPropItemStr( H_NET_DATE_TIME );
|
|
|
|
// Check for HTI and BES files inside the DSC.
|
|
CString strTmpHTI= ptrTopic->GetMultilineNetProp( H_NET_HTI_ONLINE, _T("%s\r\n") );
|
|
if (strTmpHTI.GetLength())
|
|
bHTIinsideOfDSC= true;
|
|
CString strTmpBES= ptrTopic->GetNetPropItemStr( H_NET_BES );
|
|
if (strTmpBES.GetLength())
|
|
bBESinsideOfDSC= true;
|
|
}
|
|
|
|
strTmp2 = strTmp.GetLength() ? strTmp : _T("Unavailable");
|
|
AppendNameAndValueAsRow(m_strText, _T("Last revision date/time of DSC:"), strTmp2);
|
|
}
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
|
|
m_strText += _T("<TABLE BORDER=\"1\" BORDERCOLOR=");
|
|
m_strText += k_strTableBorderColor;
|
|
m_strText += _T(" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
|
|
strTmp2 = CString(_T("<BR>")) + topicInfo.GetStrHtiFileCreated();
|
|
if (strHti.GetLength())
|
|
strTmp= _T("<BR>") + strHti;
|
|
else if (bHTIinsideOfDSC)
|
|
{
|
|
// Use DSC file settings.
|
|
strTmp = CString(_T("<BR>")) + (strDsc.GetLength() ? strDsc : _T("Unknown"));
|
|
strTmp2 = CString(_T("<BR>")) + topicInfo.GetStrDscFileCreated();
|
|
}
|
|
else
|
|
strTmp= _T("<BR>Unknown");
|
|
AppendTwoNamesAndValueAsRow(m_strText, _T("HTI file:"), strTmp, strTmp2);
|
|
|
|
strTmp2 = CString(_T("<BR>")) + topicInfo.GetStrBesFileCreated();
|
|
if (strBes.GetLength())
|
|
strTmp= _T("<BR>") + strBes;
|
|
else if (bBESinsideOfDSC)
|
|
{
|
|
// Use DSC file settings.
|
|
strTmp = CString(_T("<BR>")) + (strDsc.GetLength() ? strDsc : _T("Unknown"));
|
|
strTmp2 = CString(_T("<BR>")) + topicInfo.GetStrDscFileCreated();
|
|
}
|
|
else
|
|
strTmp= _T("<BR>Unknown");
|
|
AppendTwoNamesAndValueAsRow(m_strText, _T("BES file:"), strTmp, strTmp2);
|
|
|
|
if (pTopicInCatalog->GetTopicInfoMayNotBeCurrent())
|
|
{
|
|
m_strText += _T("<TR>\n");
|
|
m_strText += _T("<TD COLSPAN=3 ALIGN=\"CENTER\" BGCOLOR=\"#CCCC99\" >\n");
|
|
m_strText += _T("<BR>***BES or HTI may recently have changed, and data may not yet be updated.***");
|
|
m_strText += _T("</TD>\n");
|
|
m_strText += _T("</TR>\n");
|
|
}
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<TABLE BORDER=\"1\" BORDERCOLOR=");
|
|
m_strText += k_strTableBorderColor;
|
|
m_strText += _T(" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdTopicEvent, topicInfo.GetNetworkName()));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterFirstDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/time of first becoming aware of this topic:"), strTmp);
|
|
}
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdTopicLoad, topicInfo.GetNetworkName()));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterFirstDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/time of first attempted load of this topic:"), strTmp);
|
|
}
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdTopicLoadOK, topicInfo.GetNetworkName()));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterFirstDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/time of first successful load of this topic:"), strTmp);
|
|
}
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdTopicEvent, topicInfo.GetNetworkName()));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterLastDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/time of most recent change (detected by directory monitor) or reload request (from an operator) to this topic:"), strTmp);
|
|
}
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdTopicLoad, topicInfo.GetNetworkName()));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterTotal(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Count of attempted loads of this topic:"), strTmp);
|
|
}
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdTopicLoad, topicInfo.GetNetworkName()));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterLastDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/time of most recent attempted load of this topic:"), strTmp);
|
|
}
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdTopicLoadOK, topicInfo.GetNetworkName()));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterTotal(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Count of successful loads of this topic:"), strTmp);
|
|
}
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdTopicLoadOK, topicInfo.GetNetworkName()));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterLastDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/time of most recent successful load of this topic:"), strTmp);
|
|
}
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdTopicHit, topicInfo.GetNetworkName()));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterFirstDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/time of first user hit on this topic:"), strTmp);
|
|
}
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdTopicHit, topicInfo.GetNetworkName()));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterLastDateTime(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Date/time of most recent hit:"), strTmp);
|
|
}
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdTopicHit, topicInfo.GetNetworkName()));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterTotal(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Total count of hits since system startup:"), strTmp);
|
|
}
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<br>\n");
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdTopicHit, topicInfo.GetNetworkName()));
|
|
if (curr_counter)
|
|
{
|
|
DisplayTextAsTable(m_strText, _T("Daily/hourly count of hits"), 1);
|
|
m_strText += CDisplayCounterDailyHourly(curr_counter, &daily, &hourly).Display();
|
|
}
|
|
|
|
m_strText += _T("</TABLE>\n");
|
|
m_strText += _T("<br>\n");
|
|
m_strText += _T("<TABLE BORDER=\"1\" BORDERCOLOR=\"#000000\" CELLPADDING=\"2\" CELLSPACING=\"0\" WIDTH=100%>\n");
|
|
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdTopicHitNewCookie, topicInfo.GetNetworkName()));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterTotal(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Hits without cookie (presumably first hit by this user):"), strTmp);
|
|
}
|
|
|
|
curr_counter = (CHourlyDailyCounter*)Get_g_CounterMgr()->Get(CCounterLocation(CCounterLocation::eIdTopicHitOldCookie, topicInfo.GetNetworkName()));
|
|
if (curr_counter)
|
|
{
|
|
strTmp = CDisplayCounterTotal(curr_counter).Display();
|
|
AppendNameAndValueAsRow(m_strText, _T("Hits with cookie (presumably not first hit by this user):"), strTmp);
|
|
}
|
|
m_strText += _T("</TABLE>\n");
|
|
if (CTopicInCatalog::eFail != pTopicInCatalog->GetTopicStatus())
|
|
{
|
|
BeginSelfAddressingForm();
|
|
m_strText += _T("<INPUT TYPE=hidden NAME=\"");
|
|
m_strText += C_TOPIC;
|
|
m_strText += _T("\" VALUE=\"");
|
|
m_strText += topic_name;
|
|
m_strText += _T("\">\n");
|
|
m_strText += _T("<INPUT TYPE=SUBMIT VALUE=\"");
|
|
m_strText += _T("Problem Page for ");
|
|
m_strText += topic_name;
|
|
m_strText += _T("\">\n");
|
|
m_strText += _T("</FORM>\n");
|
|
}
|
|
|
|
BeginSelfAddressingForm();
|
|
InsertPasswordInForm();
|
|
m_strText += _T("<INPUT TYPE=hidden NAME=\"");
|
|
m_strText += C_FURTHER_GLOBAL;
|
|
// Value here is not actually relevant; effectively used as a comment.
|
|
m_strText += _T("\" VALUE=\"Further Global Status Page\">\n");
|
|
m_strText += _T("<INPUT TYPE=SUBMIT VALUE=\"Further Global Status Page\">\n");
|
|
m_strText += _T("</FORM>\n");
|
|
|
|
BeginSelfAddressingForm();
|
|
InsertPasswordInForm();
|
|
m_strText += _T("<INPUT TYPE=hidden NAME=\"");
|
|
m_strText += C_THREAD_OVERVIEW;
|
|
// Value here is not actually relevant; effectively used as a comment.
|
|
m_strText += _T("\" VALUE=\"Thread Status Overview Page\">\n");
|
|
m_strText += _T("<INPUT TYPE=SUBMIT VALUE=\"Thread Status Overview Page\">\n");
|
|
m_strText += _T("</FORM>\n");
|
|
|
|
BeginSelfAddressingForm();
|
|
InsertPasswordInForm();
|
|
m_strText += _T("<INPUT TYPE=hidden NAME=\"");
|
|
m_strText += C_FIRST;
|
|
// Value here is not actually relevant; effectively used as a comment.
|
|
m_strText += _T("\" VALUE=\"Front Page\">\n");
|
|
m_strText += _T("<INPUT TYPE=SUBMIT VALUE=\"Front Page\">\n");
|
|
m_strText += _T("</FORM>\n");
|
|
//m_strText += _T("</TABLE>\n");
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
m_strText += _T("</body></html>\n");
|
|
}
|