|
|
/*++
Copyright (c) 1997-2000 Microsoft Corporation
Module Name:
report.c
Abstract:
Manipulation routines for cpdata structures.
Author:
Melur Raghuraman (mraghu) 03-Oct-1997
Environment:
Revision History: Corey Morgan (coreym) 04-June-2002 Reformatted report output to XML.
--*/
#include <stdlib.h>
#include <stdio.h>
#include "cpdata.h"
#include "tracectr.h"
#include <ntverp.h>
#include "item.h"
#define MODULE_STRING_SIZE 256
#define FILE_NAME_COLUMN_SIZE 80
#define URL_NAME_COLUMN_SIZE 79
#define MAX_GUID_STRING_SIZE 64
#define DISPLAY_SIZE 10
extern PTRACE_CONTEXT_BLOCK TraceContext; extern ULONG TotalEventsLost; extern ULONG TotalEventCount; extern ULONG TimerResolution; extern __int64 ElapseTime; extern ULONG TotalBuffersRead;
extern BOOLEAN XPorHigher;
extern FARPROC EtwpIpv4ToStringA; extern FARPROC EtwpIpv4ToStringW; extern FARPROC EtwpIpv6ToStringA; extern FARPROC EtwpIpv6ToStringW;
static FILE* procFile; static void PrintDiskTotals(); static void PrintProcessCpuTime(); static void PrintProcessData(); static void PrintPerThreadPerDiskTable(); static void WriteTransactionStatistics(); static void WriteTransactionCPUTime(); static void PrintProcessSubDataInclusive(); static void PrintProcessSubDataExclusive(); void TransInclusive( PLIST_ENTRY TrHead, ULONG level );
static void ReportHotFileInfo(); static void ReportPrintJobInfo();
PIIS_REPORT_RECORD IIS = NULL; ULONG RequestsDiscarded = 0; ULONG SendErrorRequests = 0; void ProcessIisRequest(HTTP_REQUEST_RECORD *pReq); static void ReportIisEvents();
extern GUID PrintJobGuid; extern GUID UlGuid;
#ifdef DBG
BOOLEAN TracectrDbgEnabled = FALSE; #endif
PWCHAR CpdiGuidToString( PWCHAR s, ULONG len, LPGUID piid );
PCHAR RemoveCtrlCharA( PCHAR String, ULONG NumChars );
PCHAR ReduceStringA( PCHAR OutString, ULONG NumChars, PCHAR LongString );
PWCHAR ReduceStringW( PWCHAR OutString, ULONG NumChars, PWCHAR LongString );
ULONG ReportFlags = 0;
void DecodeIpAddressA( USHORT AddrType, PULONG IpAddrV4, PUSHORT IpAddrV6, PCHAR pszA ) { if (AddrType == TDI_ADDRESS_TYPE_IP) { if (XPorHigher && EtwpIpv4ToStringA != NULL) { struct in_addr IPv4Addr = * (struct in_addr UNALIGNED*) IpAddrV4;
pszA = (PCHAR)(*EtwpIpv4ToStringA)(&IPv4Addr, pszA); *pszA = '\0'; } else { StringCchCopyA(pszA, MAX_ADDRESS_LENGTH, "Undecodable IP Address"); } } else if (AddrType == TDI_ADDRESS_TYPE_IP6) { if (XPorHigher && EtwpIpv6ToStringA != NULL) { struct in6_addr IPv6Addr = * (struct in6_addr UNALIGNED*) IpAddrV6;
pszA = (PCHAR)(*EtwpIpv6ToStringA)(&IPv6Addr, pszA); *pszA = '\0'; } else { StringCchCopyA(pszA, MAX_ADDRESS_LENGTH, "Undecodable IP Address"); } } else { StringCchCopyA(pszA, MAX_ADDRESS_LENGTH, "Unknown IP Address Type"); } }
void DecodeIpAddressW( USHORT AddrType, PULONG IpAddrV4, PUSHORT IpAddrV6, PWCHAR pszW ) { if (AddrType == TDI_ADDRESS_TYPE_IP) { if (XPorHigher && EtwpIpv4ToStringW != NULL) { struct in_addr IPv4Addr = * (struct in_addr UNALIGNED*) IpAddrV4;
pszW = (PWCHAR)(*EtwpIpv4ToStringW)(&IPv4Addr, pszW); *pszW = L'\0'; } else { StringCchCopyW(pszW, MAX_ADDRESS_LENGTH, L"Undecodable IP Address"); } } else if (AddrType == TDI_ADDRESS_TYPE_IP6) { if (XPorHigher && EtwpIpv6ToStringW != NULL) { struct in6_addr IPv6Addr = * (struct in6_addr UNALIGNED*) IpAddrV6;
pszW = (PWCHAR)(*EtwpIpv6ToStringW)(&IPv6Addr, pszW); *pszW = L'\0'; } else { StringCchCopyW(pszW, MAX_ADDRESS_LENGTH, L"Undecodable IP Address"); } } else { StringCchCopyW(pszW, MAX_ADDRESS_LENGTH, L"Unknown IP Address Type"); } }
// URLs may contain non-printable characters. This routine removes them.
PCHAR RemoveCtrlCharA( PCHAR String, ULONG NumChars ) { ULONG i; for (i = 0 ; i <= NumChars && String[i] != '\0'; i++) { if ( isprint(String[i]) == 0 || String[i] == '\t' || String[i] == '\b' || String[i] == '\n' || String[i] == '\'' || String[i] == '\"') { String[i] = '?'; } }
return String; }
PCHAR ReduceStringA( PCHAR OutString, ULONG NumChars, PCHAR LongString ) { ULONG Size; ULONG i;
if (LongString == NULL) { return NULL; } // We assume here that LongString is not junk.
Size = strlen(LongString);
if (OutString == NULL) { return NULL; } RtlZeroMemory(OutString, NumChars); // This function is only useful when the length of LongString exceeds NumChars.
// However, it still works when the length of LongString is smaller than NumChars.
if (Size <= (NumChars - 1)) { StringCchCopyA(OutString, NumChars, LongString); return OutString; }
i = Size - 1; while (LongString[i] != '\\' && LongString[i] != '/' && i > 0) { i--; } if (i == 0) { // there's no /s or \s. Just truncate.
StringCchCopyA(OutString, NumChars, LongString); return OutString; } else { if ((Size - i) >= NumChars - 3) { // only name exceeds given chars.
StringCchPrintfA(OutString, NumChars, "..%s", &LongString[1]); return OutString; } else { ULONG SpareChars = (NumChars - 3) - (Size - i); StringCchCopyA(OutString, SpareChars + 1, LongString); StringCchCatA(OutString, NumChars + 1, ".."); StringCchCatA(OutString, NumChars + 1, &LongString[i]); return OutString; } } }
PWCHAR ReduceStringW( PWCHAR OutString, ULONG NumChars, PWCHAR LongString ) { ULONG Size; ULONG i;
if (LongString == NULL) { return NULL; } // We assume here that LongString is not junk.
Size = wcslen(LongString);
if (OutString == NULL) { return NULL; } RtlZeroMemory(OutString, NumChars * sizeof(WCHAR)); // This function is only useful when the length of LongString exceeds NumChars.
// However, it still works when the length of LongString is smaller than NumChars.
if (Size <= (NumChars - 1)) { StringCchCopyW(OutString, NumChars, LongString); return OutString; }
i = Size - 1; while (LongString[i] != L'\\' && LongString[i] != L'/' && i > 0) { i--; } if (i == 0) { // there's no /s or \s. Just truncate.
StringCchCopyW(OutString, NumChars, LongString); return OutString; } else { if ((Size - i) >= NumChars - 3) { // only name exceeds given chars.
StringCchPrintfW(OutString, NumChars, L"..%ws", &LongString[1]); return OutString; } else { ULONG SpareChars = (NumChars - 3) - (Size - i); StringCchCopyW(OutString, SpareChars + 1, LongString); StringCchCatW(OutString, NumChars + 1, L".."); StringCchCatW(OutString, NumChars + 1, &LongString[i]); return OutString; } } }
void CollapseTree( PLIST_ENTRY OldTree, PLIST_ENTRY NewTree, BOOL flat ) { PLIST_ENTRY OldNext; PTRANS_RECORD pTrans; PTRANS_RECORD pNewTrans;
OldNext = OldTree->Flink;
while (OldNext != OldTree) { pTrans = CONTAINING_RECORD(OldNext, TRANS_RECORD, Entry); OldNext = OldNext->Flink; pNewTrans = FindTransByList(NewTree, pTrans->pGuid, 0); if( NULL != pNewTrans ){ pNewTrans->KCpu += pTrans->KCpu; pNewTrans->UCpu += pTrans->UCpu; pNewTrans->RefCount += pTrans->RefCount; pNewTrans->RefCount1 += pTrans->RefCount1;
if (flat) { CollapseTree(&pTrans->SubTransListHead, NewTree, TRUE ); } else { CollapseTree(& pTrans->SubTransListHead, & pNewTrans->SubTransListHead, FALSE); } } } }
#define BARLEN 70
char* TimeWindowBar( char* buffer, ULONGLONG min, ULONGLONG max ) { double unit; ULONGLONG duration; int pre, bar, count, index;
if(buffer == NULL){ return NULL; } duration = ((CurrentSystem.EndTime - CurrentSystem.StartTime) / 10000000); unit = (double)BARLEN/(ULONG)duration; pre = (int)((ULONG)((min - CurrentSystem.StartTime)/10000000) * unit); bar = (int)((ULONG)((max - min)/10000000) * unit); buffer[0] = '\0'; count = 0; index = 0; while(count < pre) { buffer[index] = ' '; index++; count++; } buffer[index] = '|'; index++; count = 0; while(count < bar) { buffer[index] = '_'; index++; count++; } buffer[index] = '|'; buffer[index + 1] = '\0'; return buffer; }
char* GetDateString( char* buffer, size_t cchBuffer, ULONGLONG llTime ) { FILETIME ft, lft; SYSTEMTIME st; LARGE_INTEGER LargeTmp; BOOL bResult; HRESULT hr; WCHAR wDate[128]; CHAR aDate[128];
LargeTmp.QuadPart = llTime; ft.dwHighDateTime = LargeTmp.HighPart; ft.dwLowDateTime = LargeTmp.LowPart; FileTimeToLocalFileTime(&ft, &lft);
bResult = FileTimeToSystemTime ( &lft, &st );
if( ! bResult || st.wMonth > 12 ){ buffer[0] = '\0'; }else{
GetDateFormatW( LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, wDate, 128 );
WideCharToMultiByte( CP_UTF8, 0, wDate, wcslen(wDate)+1, aDate, 128, NULL, NULL );
hr = StringCchCopyA( buffer, cchBuffer, aDate ); hr = StringCchCatA( buffer, cchBuffer, " " );
GetTimeFormatW( LOCALE_USER_DEFAULT, 0, &st, NULL, wDate, 128 );
WideCharToMultiByte( CP_UTF8, 0, wDate, wcslen(wDate)+1, aDate, 128, NULL, NULL );
hr = StringCchCatA( buffer, cchBuffer, aDate ); }
return buffer; }
void WriteProc( LPWSTR ProcFileName, ULONG flags, PVOID pUserContext ) { ULONGLONG duration; PLIST_ENTRY Next, Head; PPROCESS_FILE_RECORD pFileRec; char buffer[MAXSTR]; BOOL bResult;
ReportFlags = flags;
procFile = _wfopen(ProcFileName, L"w"); if (procFile == NULL) return;
fprintf( procFile, "<?xml version=\"1.0\" encoding='UTF-8'?>\n" );
if( !(TraceContext->Flags & TRACE_TRANSFORM_XML ) && TraceContext->XSLDocName != NULL ){ fprintf( procFile, "<?xml-stylesheet type=\"text/xsl\" href=\"%ws\"?>\n", TraceContext->XSLDocName ); } fprintf( procFile, "<report>\n<header>\n" );
fprintf( procFile, "<version>%d</version>\n", VER_PRODUCTBUILD ); fprintf( procFile, "<type>%s</type>\n", ( ReportFlags & TRACE_TOTALS_REPORT ) ? "Total" : "Default" ); fprintf( procFile, "<build>%d</build>\n",CurrentSystem.BuildNumber ); fprintf( procFile, "<processors>%d</processors>\n", CurrentSystem.NumberOfProcessors );
if (CurrentSystem.CpuSpeed > 0) { fprintf(procFile, "<cpu_speed units='MHz'>%d</cpu_speed>\n", CurrentSystem.CpuSpeed ); } else { fprintf(procFile, "<cpu_speed/>\n" ); } if (CurrentSystem.MemorySize > 0) { fprintf(procFile, "<memory units='Mb'>%d</memory>\n", CurrentSystem.MemorySize ); } else { fprintf(procFile, "<memory/>\n" ); }
if (CurrentSystem.ComputerName != NULL) { fprintf(procFile, "<computer_name>%ws</computer_name>\n", CurrentSystem.ComputerName ); } else { fprintf(procFile, "<computer_name/>\n" ); }
fprintf( procFile, "<start>%s</start>\n", GetDateString( buffer, MAXSTR, CurrentSystem.StartTime ) );
fprintf( procFile, "<end>%s</end>\n", GetDateString( buffer, MAXSTR, CurrentSystem.EndTime) );
duration = (CurrentSystem.EndTime - CurrentSystem.StartTime) / 10000000; fprintf( procFile, "<duration>%I64u</duration>\n",duration );
Head = &CurrentSystem.ProcessFileListHead; Next = Head->Flink; while (Next != Head) { pFileRec = CONTAINING_RECORD( Next, PROCESS_FILE_RECORD, Entry ); Next = Next->Flink;
fprintf( procFile, "<trace name=\"%ws\">\n", pFileRec->TraceName ? pFileRec->TraceName : L"-" ); fprintf( procFile, "<file>%ws</file>\n", pFileRec->FileName ? pFileRec->FileName : L"-" );
if (pFileRec->StartTime == 0){ pFileRec->StartTime = CurrentSystem.StartTime; } if (pFileRec->EndTime == 0){ pFileRec->EndTime = CurrentSystem.EndTime; }
fprintf( procFile, "<start>%s</start>\n", GetDateString( buffer, MAXSTR, pFileRec->StartTime ) ); duration = (pFileRec->EndTime - pFileRec->StartTime) / 10000000; fprintf( procFile, "<end>%s</end>\n" "<duration>%I64u</duration>\n", GetDateString( buffer, MAXSTR, pFileRec->EndTime ), duration ); fprintf( procFile, "<duration_window xml:space='preserve'>%s</duration_window>\n", TimeWindowBar(buffer, pFileRec->StartTime, pFileRec->EndTime) ); fprintf( procFile, "</trace>\n" );
}
fprintf( procFile, "</header>\n" );
if (flags & (TRACE_BASIC_REPORT|TRACE_TOTALS_REPORT)){ PMOF_INFO pMofInfo; WriteTransactionStatistics(); WriteTransactionCPUTime();
pMofInfo = GetMofInfoHead ((LPCGUID)&PrintJobGuid); if ( pMofInfo != NULL ){ if (pMofInfo->EventCount > 0) { ReportPrintJobInfo(); } }
pMofInfo = GetMofInfoHead ((LPCGUID)&UlGuid); if ( pMofInfo != NULL ){ if (pMofInfo->EventCount > 0) { ReportIisEvents(); } }
// PrintProcessData() must be run before others to set the process
// time from the added thread times
PrintProcessData();
PrintProcessSubDataExclusive(); PrintProcessSubDataInclusive(); /*
PrintProcessCpuTime(); */
PrintDiskTotals(); PrintPerThreadPerDiskTable();
pMofInfo = GetMofInfoHead ((LPCGUID)&FileIoGuid); if ( pMofInfo != NULL ) { pMofInfo = GetMofInfoHead ((LPCGUID)&DiskIoGuid); if ( pMofInfo != NULL ) { ReportHotFileInfo(); } } }
fprintf( procFile, "</report>\n" ); fclose(procFile); }
static void PrintDiskTotals() { // Print the Disk Table.
PTDISK_RECORD pDisk; PLIST_ENTRY Next, Head; ULONG rio, wio;
ULONGLONG Duration = (ULONGLONG)((CurrentSystem.EndTime - CurrentSystem.StartTime) / 10000000);
if (Duration == 0) { return; }
Head = &CurrentSystem.GlobalDiskListHead; Next = Head->Flink; if( Next == Head ){ return; }
fprintf(procFile, "<table title='Disk Totals'>\n" );
Head = &CurrentSystem.GlobalDiskListHead; Next = Head->Flink; while (Next != Head) { pDisk = CONTAINING_RECORD( Next, TDISK_RECORD, Entry ); rio = pDisk->ReadCount + pDisk->HPF; wio = pDisk->WriteCount;
fprintf( procFile, "<disk number=\"%d\">\n", pDisk->DiskNumber ); fprintf( procFile, "<read_rate>%1.3f</read_rate>\n", (double)rio / ((double)Duration) ); fprintf( procFile, "<read_size>%d</read_size>\n", (rio == 0) ? 0 : (pDisk->ReadSize + pDisk->HPFSize) / rio ); fprintf( procFile, "<write_rate>%1.3f</write_rate>\n", (double)wio / ((double)Duration)); fprintf( procFile, "<write_size>%d</write_size>\n", (wio == 0) ? 0 : pDisk->WriteSize / wio ); fprintf( procFile, "</disk>\n" );
Next = Next->Flink; }
fprintf(procFile, "</table>\n" ); }
void TotalTransChildren( PLIST_ENTRY Head, ULONG *Kernel, ULONG *User, LONG level ) { PTRANS_RECORD pTrans; PLIST_ENTRY Next; Next = Head->Flink; while( Next != Head ){ pTrans = CONTAINING_RECORD( Next, TRANS_RECORD, Entry ); Next = Next->Flink; TotalTransChildren( &pTrans->SubTransListHead, Kernel, User, level+1 ); *Kernel += pTrans->KCpu; *User += pTrans->UCpu; } }
void PrintTransList( PLIST_ENTRY TrHead, LONG level ) { PTRANS_RECORD pTrans; PMOF_INFO pMofInfo; ULONG Kernel; ULONG User; WCHAR str[MAXSTR]; WCHAR buffer[MAXSTR]; PLIST_ENTRY TrNext = TrHead->Flink; while( TrNext != TrHead ){ int count = 0; pTrans = CONTAINING_RECORD( TrNext, TRANS_RECORD, Entry ); TrNext = TrNext->Flink; Kernel = pTrans->KCpu; User = pTrans->UCpu; pMofInfo = GetMofInfoHead( pTrans->pGuid); if (pMofInfo == NULL) { return; }
StringCchCopyW ( buffer, MAXSTR, ( pMofInfo->strDescription ? pMofInfo->strDescription : CpdiGuidToString( str, MAXSTR, &pMofInfo->Guid ) ));
TotalTransChildren( &pTrans->SubTransListHead, &Kernel, &User, 0 );
fprintf( procFile, "<transaction name=\"%ws\">\n", buffer ); fprintf( procFile, "<count>%d</count>\n", pTrans->RefCount ); fprintf( procFile, "<kernel>%d</kernel>\n", Kernel ); fprintf( procFile, "<user>%d</user>\n", User ); fprintf( procFile, "\n<transaction>\n" );
if( level <= MAX_TRANS_LEVEL ){ PrintTransList( &pTrans->SubTransListHead, level+1 ); } } }
static void PrintProcessCpuTime() { PTHREAD_RECORD pThread; PPROCESS_RECORD pProcess; ULONGLONG lLifeTime; ULONG TotalUserTime = 0; ULONG TotalKernelTime = 0; ULONG TotalCPUTime = 0; PLIST_ENTRY Next, Head; PLIST_ENTRY ThNext, ThHead; BOOL titled; ULONG usedThreadCount; ULONG ThreadCount; ULONG ProcessUTime; ULONG ProcessKTime; ULONG ThreadKCPU; ULONG ThreadUCPU;
Head = &CurrentSystem.ProcessListHead; Next = Head->Flink; if( Head == Next ){ return; }
fprintf( procFile, "<table title='Process/Thread CPU Time Statistics'>\n" );
Head = &CurrentSystem.ProcessListHead; Next = Head->Flink; while (Next != Head) { pProcess = CONTAINING_RECORD( Next, PROCESS_RECORD, Entry ); lLifeTime = CalculateProcessLifeTime(pProcess);
fprintf(procFile, "<process name=\"%ws\">" "<pid>0x%04X</pid>" "<kernel>%d</kernel>" "<user>%d</user>" "<read>%d</read>" "<read_size>%1.2f</read_size>" "<write>%d</write>" "<write_size>%1.2f</write_size>" "<send>%d</send>" "<send_size>%1.2f</send_size>" "<recv>%5d</recv>" "<recv_size>%.2f</recv_size>" "<duation>%I64u</duation>\n", (pProcess->ImageName) ? pProcess->ImageName : L"Idle", pProcess->PID, CalculateProcessKCPU(pProcess), CalculateProcessUCPU(pProcess), pProcess->ReadIO + pProcess->HPF, (pProcess->ReadIO + pProcess->HPF) ? (double)(pProcess->ReadIOSize + pProcess->HPFSize)/ (double)(pProcess->ReadIO + pProcess->HPF) : 0, pProcess->WriteIO, pProcess->WriteIO ? (double)pProcess->WriteIOSize/(double)pProcess->WriteIO : 0, pProcess->SendCount, pProcess->SendCount ? (double)(pProcess->SendSize / 1024)/(double)pProcess->SendCount : 0, pProcess->RecvCount, pProcess->RecvCount ? (double)(pProcess->RecvSize / 1024) / (double)pProcess->RecvCount : 0, (lLifeTime / 10000000 ) );
ThHead = &pProcess->ThreadListHead; ThNext = ThHead->Flink; titled = FALSE; usedThreadCount = 0; ThreadCount = 0; ProcessUTime = 0; ProcessKTime = 0; while (ThNext != ThHead) { pThread = CONTAINING_RECORD( ThNext, THREAD_RECORD, Entry ); ThreadKCPU = (pThread->KCPUEnd - pThread->KCPUStart) * CurrentSystem.TimerResolution; ThreadUCPU = (pThread->UCPUEnd - pThread->UCPUStart) * CurrentSystem.TimerResolution; if( pThread->ReadIO || pThread->WriteIO || ThreadKCPU || ThreadUCPU || pThread->SendCount || pThread->RecvCount || pThread->HPF ){
fprintf(procFile, "<thread>" "<tid>0x%04I64X</tid>" "<kernel>%d</kernel>" "<user>%d</user>" "<read>%d</read>" "<read_size>%1.2f</read_size>" "<write>%d</write>" "<write_size>%1.2f</write_size>" "<send>%d</send>" "<send_size>%1.2f</send_size>" "<recv>%d</recv>" "<recv_size>%1.2f</recv_size>" "<duration>%I64u</duration>" "</thread>\n", pThread->TID, ThreadKCPU, ThreadUCPU, pThread->ReadIO + pThread->HPF, pThread->ReadIO + pThread->HPF ? (double)(pThread->ReadIOSize + pThread->HPFSize)/ (double)(pThread->ReadIO + pThread->HPF) : 0, pThread->WriteIO, pThread->WriteIO ? (double)pThread->WriteIOSize/ (double)pThread->WriteIO : 0, pThread->SendCount, pThread->SendCount ? (double)(pThread->SendSize / 1024)/(double)pThread->SendCount : 0, pThread->RecvCount, pThread->RecvCount ? (double)(pThread->RecvSize / 1024)/(double)pThread->RecvCount : 0, ((pThread->TimeEnd - pThread->TimeStart) / 10000000) ); }
PrintTransList( &pThread->TransListHead, 0 ); TotalUserTime += ThreadUCPU; TotalKernelTime += ThreadKCPU; TotalCPUTime += ThreadKCPU + ThreadUCPU; ThNext = ThNext->Flink; }
fprintf( procFile, "</process>\n" );
Next = Next->Flink; }
fprintf( procFile, "</table>\n" ); }
static void PrintProcessData() { PTHREAD_RECORD pThread; PPROCESS_RECORD pProcess; PTRANS_RECORD pTrans;
PLIST_ENTRY Next, Head; PLIST_ENTRY ThNext, ThHead; PLIST_ENTRY TrNext, TrHead; ULONG usedThreadCount; ULONG ThreadCount; ULONG TotalusedThreadCount = 0; ULONG TotalThreadCount = 0;
ULONG ThreadUTime; ULONG ThreadKTime; ULONG ThreadUTimeTrans; ULONG ThreadKTimeTrans; ULONG ThreadUTimeNoTrans; ULONG ThreadKTimeNoTrans;
ULONG CountThreadNoTrans; ULONG TotalKCPUThreadNoTrans; ULONG TotalUCPUThreadNoTrans; double PercentThreadNoTrans;
ULONG CountThreadTrans; ULONG TotalKCPUThreadTrans; ULONG TotalUCPUThreadTrans; double PercentThreadTrans;
ULONG TransUTime; ULONG TransKTime; ULONG Processors;
ULONG TotalKThread = 0; ULONG TotalUThread = 0;
ULONG TotalKTrans = 0; ULONG TotalUTrans = 0; double PerTotal = 0.0; double IdlePercent = 0.0; double percent; double percentTrans; double lDuration;
Head = &CurrentSystem.ProcessListHead; Next = Head->Flink; if( Head == Next ){ return; }
Processors = CurrentSystem.NumberOfProcessors ? CurrentSystem.NumberOfProcessors : 1; lDuration = ((double)((LONGLONG)(CurrentSystem.EndTime - CurrentSystem.StartTime))) / 10000000.00;
fprintf( procFile, "<table title='Image Statistics'>\n" );
Head = &CurrentSystem.ProcessListHead; Next = Head->Flink; while (Next != Head) { pProcess = CONTAINING_RECORD( Next, PROCESS_RECORD, Entry );
ThHead = &pProcess->ThreadListHead; ThNext = ThHead->Flink;
usedThreadCount = 0; ThreadCount = 0; ThreadUTime = 0; ThreadKTime = 0; ThreadUTimeTrans = 0; ThreadKTimeTrans = 0; ThreadUTimeNoTrans = 0; ThreadKTimeNoTrans = 0; TransKTime = 0; TransUTime = 0; percent = 0;
CountThreadNoTrans = 0; TotalKCPUThreadNoTrans = 0; TotalUCPUThreadNoTrans = 0;
CountThreadTrans = 0; TotalKCPUThreadTrans = 0; TotalUCPUThreadTrans = 0;
while (ThNext != ThHead) { LIST_ENTRY NewTransList;
pThread = CONTAINING_RECORD( ThNext, THREAD_RECORD, Entry ); if( pThread->ReadIO || pThread->WriteIO || pThread->KCPUEnd > pThread->KCPUStart || pThread->UCPUEnd > pThread->UCPUStart || pThread->SendCount || pThread->RecvCount || pThread->HPF ) { usedThreadCount++; TotalusedThreadCount++; } ThreadCount++; TotalThreadCount++;
ThreadUTime += (pThread->UCPUEnd - pThread->UCPUStart) * CurrentSystem.TimerResolution; ThreadKTime += (pThread->KCPUEnd - pThread->KCPUStart) * CurrentSystem.TimerResolution; ThreadKTimeTrans += pThread->KCPU_Trans * CurrentSystem.TimerResolution; ThreadUTimeTrans += pThread->UCPU_Trans * CurrentSystem.TimerResolution; ThreadKTimeNoTrans += pThread->KCPU_NoTrans * CurrentSystem.TimerResolution; ThreadUTimeNoTrans += pThread->UCPU_NoTrans * CurrentSystem.TimerResolution;
if (pThread->KCPU_Trans + pThread->UCPU_Trans == 0) { CountThreadNoTrans ++; TotalKCPUThreadNoTrans += pThread->KCPU_NoTrans * CurrentSystem.TimerResolution; TotalUCPUThreadNoTrans += pThread->UCPU_NoTrans * CurrentSystem.TimerResolution; } else { CountThreadTrans ++; TotalKCPUThreadTrans += ( pThread->KCPU_Trans + pThread->KCPU_NoTrans) * CurrentSystem.TimerResolution; TotalUCPUThreadTrans += ( pThread->UCPU_Trans + pThread->UCPU_NoTrans) * CurrentSystem.TimerResolution; }
InitializeListHead(& NewTransList); CollapseTree(& pThread->TransListHead, & NewTransList, TRUE); TrHead = & NewTransList; TrNext = TrHead->Flink; while( TrNext != TrHead ){ pTrans = CONTAINING_RECORD( TrNext, TRANS_RECORD, Entry ); TransUTime += pTrans->UCpu; TransKTime += pTrans->KCpu; TrNext = TrNext->Flink; } DeleteTransList(& NewTransList, 0);
ThNext = ThNext->Flink; }
TotalKThread += ThreadKTime; TotalUThread += ThreadUTime; TotalKTrans += TransKTime; TotalUTrans += TransUTime; percent = (((ThreadKTime + ThreadUTime + 0.0)/lDuration)/1000.0) * 100.0;
if (ThreadKTime + ThreadUTime == 0) { percentTrans = 0.0; PercentThreadTrans = 0.0; PercentThreadNoTrans = 0.0; } else { percentTrans = ( (ThreadKTimeTrans + ThreadUTimeTrans + 0.0) / (ThreadKTime + ThreadUTime + 0.0)) * 100.00; PercentThreadTrans = ((TotalKCPUThreadTrans + TotalUCPUThreadTrans + 0.0) / (ThreadKTime + ThreadUTime + 0.0)) * 100.00; PercentThreadNoTrans = ((TotalKCPUThreadNoTrans + TotalUCPUThreadNoTrans + 0.0) / (ThreadKTime + ThreadUTime + 0.0)) * 100.00; } PerTotal += percent; fprintf(procFile, "<image name=\"%ws\">" "<pid>0x%08X</pid>" "<threads>%d</threads>" "<used_threads>%d</used_threads>" "<process_kernel>%d</process_kernel>" "<process_user>%d</process_user>" "<transaction_kernel>%d</transaction_kernel>" "<transaction_user>%d</transaction_user>" "<cpu>%1.2f</cpu>" "</image>\n", (pProcess->ImageName) ? pProcess->ImageName : L"Idle", pProcess->PID, ThreadCount, usedThreadCount, ThreadKTime, ThreadUTime, ThreadKTimeTrans, ThreadUTimeTrans, (percent / Processors) );
if(pProcess->PID == 0){ IdlePercent += (percent / Processors ); } Next = Next->Flink; }
fprintf( procFile, "</table>\n" ); }
void TransInclusive( PLIST_ENTRY TrHead, ULONG level ) { ULONG Kernel, User; PLIST_ENTRY TrNext = TrHead->Flink; PMOF_INFO pMofInfo; PTRANS_RECORD pTrans; WCHAR buffer[MAXSTR]; WCHAR str[MAXSTR];
while( TrNext != TrHead ){ ULONG count = 0; pTrans = CONTAINING_RECORD( TrNext, TRANS_RECORD, Entry ); TrNext = TrNext->Flink; pMofInfo = GetMofInfoHead( pTrans->pGuid); if (pMofInfo == NULL) { return; } Kernel = pTrans->KCpu; User = pTrans->UCpu; TotalTransChildren( &pTrans->SubTransListHead, &Kernel, &User, 0 );
StringCchCopyW ( buffer, MAXSTR, ( pMofInfo->strDescription ? pMofInfo->strDescription : CpdiGuidToString( str, MAXSTR, &pMofInfo->Guid ) ));
fprintf(procFile, "<transaction level='%d' name=\"%ws\">" "<count>%d</count>" "<kernel>%d</kernel>" "<user>%d</user>", level, buffer, pTrans->RefCount, Kernel, User ); TransInclusive( &pTrans->SubTransListHead, level+1 );
fprintf(procFile, "</transaction>\n" ); } }
static void PrintProcessSubDataInclusive() { PPROCESS_RECORD pProcess; PTHREAD_RECORD pThread; PLIST_ENTRY Next, Head; PLIST_ENTRY TrNext; PLIST_ENTRY ThNext, ThHead; LIST_ENTRY NewHead; BOOL bTable = FALSE;
Head = &CurrentSystem.ProcessListHead; Next = Head->Flink; while (Next != Head && !bTable ) { pProcess = CONTAINING_RECORD( Next, PROCESS_RECORD, Entry ); Next = Next->Flink; if( pProcess->PID == 0 ){ continue; }
// Total up all the threads into one list
InitializeListHead( &NewHead ); ThHead = &pProcess->ThreadListHead; ThNext = ThHead->Flink; while( ThNext != ThHead ){ pThread = CONTAINING_RECORD( ThNext, THREAD_RECORD, Entry ); ThNext = ThNext->Flink; CollapseTree(&pThread->TransListHead, &NewHead, FALSE ); }
TrNext = NewHead.Flink;
if( TrNext != &NewHead ){ bTable = TRUE; } DeleteTransList( &NewHead, 0 ); } if( !bTable ){ return; }
// Walk through the Process List and Print the report.
fprintf(procFile, "<table title='Inclusive Transactions Per Process'>\n" );
Head = &CurrentSystem.ProcessListHead; Next = Head->Flink; while (Next != Head) { pProcess = CONTAINING_RECORD( Next, PROCESS_RECORD, Entry ); Next = Next->Flink; if( pProcess->PID == 0 ){ continue; }
// Total up all the threads into one list
InitializeListHead( &NewHead ); ThHead = &pProcess->ThreadListHead; ThNext = ThHead->Flink; while( ThNext != ThHead ){ pThread = CONTAINING_RECORD( ThNext, THREAD_RECORD, Entry ); ThNext = ThNext->Flink; CollapseTree(&pThread->TransListHead, &NewHead, FALSE ); }
TrNext = NewHead.Flink;
if( TrNext != &NewHead ){ fprintf(procFile, "<process name=\"%ws\">" "<pid>0x%04X</pid>\n", (pProcess->ImageName) ? pProcess->ImageName : L"Idle", pProcess->PID ); TransInclusive( &NewHead, 0 ); fprintf( procFile, "</process>\n" ); } DeleteTransList( &NewHead, 0 ); }
fprintf(procFile, "</table>\n" ); }
static void PrintProcessSubDataExclusive() { PPROCESS_RECORD pProcess; PTRANS_RECORD pTrans; PTHREAD_RECORD pThread; PLIST_ENTRY ThNext, ThHead; PMOF_INFO pMofInfo; PLIST_ENTRY Next, Head; PLIST_ENTRY TrNext; LIST_ENTRY NewHead; double percent, percentCPU, totalPerCPU; double processPart; double transPart; double totalPercent; double trans, KCPU, UCPU; WCHAR str[MAXSTR]; double duration = ((double)((LONGLONG)(CurrentSystem.EndTime - CurrentSystem.StartTime))) / 10000000.00; BOOL bTable = FALSE;
Head = &CurrentSystem.ProcessListHead; Next = Head->Flink; while (Next != Head && !bTable ) { pProcess = CONTAINING_RECORD( Next, PROCESS_RECORD, Entry ); Next = Next->Flink; if( pProcess->PID == 0 ){ continue; } InitializeListHead( &NewHead ); ThHead = &pProcess->ThreadListHead; ThNext = ThHead->Flink; while( ThNext != ThHead ){ pThread = CONTAINING_RECORD( ThNext, THREAD_RECORD, Entry ); ThNext = ThNext->Flink; CollapseTree(&pThread->TransListHead, &NewHead, TRUE ); }
TrNext = NewHead.Flink; if( TrNext != &NewHead ){ bTable = TRUE; } DeleteTransList( &NewHead, 0 ); }
if( !bTable ){ return; }
// Walk through the Process List and Print the report.
fprintf(procFile, "<table title='Exclusive Transactions Per Process'>\n" );
Head = &CurrentSystem.ProcessListHead; Next = Head->Flink; while (Next != Head) { BOOL titled = FALSE; pProcess = CONTAINING_RECORD( Next, PROCESS_RECORD, Entry ); Next = Next->Flink; if( pProcess->PID == 0 ){ continue; } InitializeListHead( &NewHead ); ThHead = &pProcess->ThreadListHead; ThNext = ThHead->Flink; while( ThNext != ThHead ){ pThread = CONTAINING_RECORD( ThNext, THREAD_RECORD, Entry ); ThNext = ThNext->Flink; CollapseTree(&pThread->TransListHead, &NewHead, TRUE ); }
TrNext = NewHead.Flink; totalPercent = 0.0; totalPerCPU = 0.0; while( TrNext != &NewHead ){ if(!titled){ fprintf(procFile, "<process name=\"%ws\">" "<pid>0x%04X</pid>\n", (pProcess->ImageName) ? pProcess->ImageName : L"Idle", pProcess->PID ); titled = TRUE; } pTrans = CONTAINING_RECORD( TrNext, TRANS_RECORD, Entry ); TrNext = TrNext->Flink; pMofInfo = GetMofInfoHead( pTrans->pGuid); if (pMofInfo == NULL) { return; } transPart = pTrans->UCpu + pTrans->KCpu; processPart = CalculateProcessKCPU(pProcess) + CalculateProcessUCPU(pProcess); percentCPU = ((((double)pTrans->KCpu + (double)pTrans->UCpu ) / 10.0 ) / duration) / ((double) CurrentSystem.NumberOfProcessors); totalPerCPU += percentCPU; if(processPart) percent = (transPart/processPart) * 100.0; else percent = 0; totalPercent += percent; if (!(ReportFlags & TRACE_TOTALS_REPORT) ){ if (pTrans->RefCount == 0 && pTrans->RefCount1 == 0) KCPU = UCPU = 0.0; else if (pTrans->RefCount == 0) { KCPU = (double) pTrans->KCpu; UCPU = (double) pTrans->UCpu; } else { KCPU = (double) pTrans->KCpu / (double) pTrans->RefCount; UCPU = (double) pTrans->UCpu / (double) pTrans->RefCount; } } else{ KCPU = (double)pTrans->KCpu; UCPU = (double)pTrans->UCpu; }
trans = (double)pTrans->RefCount / duration; fprintf(procFile, "<transaction name=\"%ws\">" "<count>%d</count>" "<rate>%1.2f</rate>" "<kernel>%1.0f</kernel>" "<user>%1.0f</user>" "<process_cpu>%1.2f</process_cpu>" "<cpu>%1.2f</cpu>" "</transaction>\n", (pMofInfo->strDescription != NULL) ? pMofInfo->strDescription : CpdiGuidToString( str, MAXSTR, &pMofInfo->Guid ), pTrans->RefCount, trans, KCPU, UCPU, percent, percentCPU ); } if( titled ){ fprintf( procFile, "</process>\n" ); } DeleteTransList( &NewHead, 0 ); } fprintf(procFile, "</table>\n" ); }
static void PrintPerThreadPerDiskTable( ) { PPROCESS_RECORD pProcess; PTDISK_RECORD pDisk; PLIST_ENTRY Next, Head; PLIST_ENTRY GNext, GHead; PLIST_ENTRY DiNext, DiHead; ULONG rio, wio, DiskNumber; BOOL bTable = FALSE; ULONGLONG Duration = (ULONGLONG)((CurrentSystem.EndTime - CurrentSystem.StartTime) / 10000000);
if (Duration == 0) { return; }
// Walk through the Process List and Print the report.
GHead = &CurrentSystem.GlobalDiskListHead; GNext = GHead->Flink; while (GNext != GHead && !bTable) {
pDisk = CONTAINING_RECORD( GNext, TDISK_RECORD, Entry); DiskNumber = pDisk->DiskNumber;
Head = &CurrentSystem.ProcessListHead; Next = Head->Flink; while (Next != Head) { pProcess = CONTAINING_RECORD( Next, PROCESS_RECORD, Entry ); DiHead = &pProcess->DiskListHead; DiNext = DiHead->Flink; while (DiNext != DiHead && !bTable) { pDisk = CONTAINING_RECORD( DiNext, TDISK_RECORD, Entry );
if (DiskNumber != pDisk->DiskNumber) { DiNext = DiNext->Flink; continue; }else{ bTable = TRUE; break; }
} Next = Next->Flink; } GNext = GNext->Flink; }
if( !bTable ){ return; }
GHead = &CurrentSystem.GlobalDiskListHead; GNext = GHead->Flink; while (GNext != GHead) {
pDisk = CONTAINING_RECORD( GNext, TDISK_RECORD, Entry); DiskNumber = pDisk->DiskNumber; fprintf( procFile, "<table title='Disk' number='%d'>\n", DiskNumber );
Head = &CurrentSystem.ProcessListHead; Next = Head->Flink; while (Next != Head) { pProcess = CONTAINING_RECORD( Next, PROCESS_RECORD, Entry );
DiHead = &pProcess->DiskListHead; DiNext = DiHead->Flink; while (DiNext != DiHead) { pDisk = CONTAINING_RECORD( DiNext, TDISK_RECORD, Entry );
if (DiskNumber != pDisk->DiskNumber) { DiNext = DiNext->Flink; continue; } rio = pDisk->ReadCount + pDisk->HPF; wio = pDisk->WriteCount; fprintf(procFile, "<image name='%ws'>" "<pid>0x%08X</pid>" "<authority>%ws</authority>" "<read_rate>%1.3f</read_rate>" "<read_size>%d</read_size>" "<write_rate>%1.3f</write_rate>" "<write_size>%d</write_size>" "</image>\n", (pProcess->ImageName) ? pProcess->ImageName : L"-", pProcess->PID, (pProcess->UserName) ? pProcess->UserName : L"-", (double)rio / ((double)Duration), (rio == 0) ? 0 : (pDisk->ReadSize + pDisk->HPFSize) / rio, (double)wio / ((double)Duration), (wio == 0) ? 0 : pDisk->WriteSize / wio ); DiNext = DiNext->Flink; } Next = Next->Flink; }
fprintf( procFile, "</table>\n" ); GNext = GNext->Flink; } }
static void WriteTransactionStatistics() { PLIST_ENTRY Head, Next; PLIST_ENTRY Dhead, DNext; ULONG trans; double KCPU, UCPU, PerCpu; double RIO, WIO, Send, Recv; PMOF_INFO pMofInfo; PMOF_DATA pMofData; double AvgRT; double TransRate; WCHAR str[MAXSTR]; double duration = ((double)((LONGLONG)(CurrentSystem.EndTime - CurrentSystem.StartTime))) / 10000000.00; BOOL bTable = FALSE;
Head = &CurrentSystem.EventListHead; Next = Head->Flink;
while (Head != Next && !bTable ) { pMofInfo = CONTAINING_RECORD(Next, MOF_INFO, Entry); Dhead = &pMofInfo->DataListHead; DNext = Dhead->Flink; while(DNext!=Dhead){ pMofData = CONTAINING_RECORD(DNext, MOF_DATA, Entry); trans = pMofData->CompleteCount; if (trans > 0) { bTable = TRUE; break; } DNext = DNext->Flink; } Next = Next->Flink; } if( !bTable ){ return; }
fprintf( procFile, "<table title='Transaction Statistics'>\n" );
Head = &CurrentSystem.EventListHead; Next = Head->Flink;
while (Head != Next) { pMofInfo = CONTAINING_RECORD(Next, MOF_INFO, Entry); Dhead = &pMofInfo->DataListHead; DNext = Dhead->Flink; while(DNext!=Dhead){ pMofData = CONTAINING_RECORD(DNext, MOF_DATA, Entry); trans = pMofData->CompleteCount; if (trans > 0) { UCPU = pMofData->UserCPU; KCPU = pMofData->KernelCPU; PerCpu = (((UCPU + KCPU)/1000.0)/duration) * 100.0; UCPU /= trans; KCPU /= trans; if(CurrentSystem.NumberOfProcessors) PerCpu/=CurrentSystem.NumberOfProcessors; if( ReportFlags & TRACE_TOTALS_REPORT ){ RIO = pMofData->ReadCount; WIO = pMofData->WriteCount; Send = pMofData->SendCount; Recv = pMofData->RecvCount; }else{ RIO = pMofData->ReadCount / trans; WIO = pMofData->WriteCount / trans; Send = pMofData->SendCount / trans; Recv = pMofData->RecvCount / trans; } AvgRT = (double)pMofData->TotalResponseTime; AvgRT /= trans; TransRate = ( (float)trans / duration );
// TODO: NOT /trans if TRACE_TOTALS_REPORT
fprintf(procFile, "<transaction name='%ws'>" "<count>%d</count>" "<response_time>%1.0f</response_time>" "<rate>%1.2f</rate>" "<cpu>%1.2f</cpu>" "<disk_read_per_trans>%1.2f</disk_read_per_trans>" "<disk_write_per_trans>%1.2f</disk_write_per_trans>" "<tcp_send_per_trans>%1.2f</tcp_send_per_trans>" "<tcp_recv_per_trans>%1.2f</tcp_recv_per_trans>" "</transaction>\n", (pMofInfo->strDescription) ? pMofInfo->strDescription : CpdiGuidToString( str, MAXSTR, &pMofInfo->Guid ), pMofData->CompleteCount, AvgRT, TransRate, PerCpu, RIO, WIO, Send, Recv ); } DNext = DNext->Flink; } Next = Next->Flink; }
fprintf(procFile, "</table>" );
}
static void WriteTransactionCPUTime() { PLIST_ENTRY Head, Next; PLIST_ENTRY Dhead, DNext; double KCPU, UCPU; PMOF_INFO pMofInfo; PMOF_DATA pMofData; double trans; double PerCpu; WCHAR str[MAXSTR]; double duration = ((double)((LONGLONG)(CurrentSystem.EndTime - CurrentSystem.StartTime))) / 10000000.00; BOOL bTable = FALSE; Head = &CurrentSystem.EventListHead; Next = Head->Flink;
while (Head != Next && !bTable ) { pMofInfo = CONTAINING_RECORD(Next, MOF_INFO, Entry); Dhead = &pMofInfo->DataListHead; DNext = Dhead->Flink; while(DNext!=Dhead){ pMofData = CONTAINING_RECORD(DNext, MOF_DATA, Entry); trans = (double)pMofData->CompleteCount; if (trans > 0) { bTable = TRUE; break; } DNext = DNext->Flink; } Next = Next->Flink; } if( !bTable ){ return; }
fprintf( procFile, "<table title='Transaction CPU Utilization'>\n" );
Head = &CurrentSystem.EventListHead; Next = Head->Flink;
while (Head != Next) { pMofInfo = CONTAINING_RECORD(Next, MOF_INFO, Entry); Dhead = &pMofInfo->DataListHead; DNext = Dhead->Flink; while(DNext!=Dhead){ pMofData = CONTAINING_RECORD(DNext, MOF_DATA, Entry); trans = (double)pMofData->CompleteCount; if (trans > 0) { UCPU = pMofData->UserCPU; UCPU /= trans; KCPU = pMofData->KernelCPU; KCPU /= trans; PerCpu = (((pMofData->UserCPU + pMofData->KernelCPU + 0.0)/1000.0)/duration) * 100.0; if( !(ReportFlags & TRACE_TOTALS_REPORT) ){ trans /= duration; } if(CurrentSystem.NumberOfProcessors){ PerCpu/=CurrentSystem.NumberOfProcessors; } // NOTE: RATE should be COUNT if TRACE_TOTALS_REPORT
fprintf(procFile, "<transaction name='%ws'>" "<rate>%1.2f</rate>" "<min_kernel>%d</min_kernel>" "<min_user>%d</min_user>" "<max_kernel>%d</max_kernel>" "<max_user>%d</max_user>" "<per_trans_kernel>%1.0f</per_trans_kernel>" "<per_trans_user>%1.0f</per_trans_user>" "<total_kernel>%d</total_kernel>" "<total_user>%d</total_user>" "<cpu>%1.2f</cpu>" "</transaction>\n", (pMofInfo->strDescription) ? pMofInfo->strDescription : CpdiGuidToString( str, MAXSTR, &pMofInfo->Guid ), trans, pMofData->MinKCpu, pMofData->MinUCpu, pMofData->MaxKCpu, pMofData->MaxUCpu, KCPU, UCPU, pMofData->KernelCPU, pMofData->UserCPU, PerCpu ); } DNext = DNext->Flink; } Next = Next->Flink; }
fprintf(procFile, "</table>\n" ); }
PWCHAR CpdiGuidToString( PWCHAR s, ULONG len, LPGUID piid ) { StringCchPrintf(s, len, L"{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", piid->Data1, piid->Data2, piid->Data3, piid->Data4[0], piid->Data4[1], piid->Data4[2], piid->Data4[3], piid->Data4[4], piid->Data4[5], piid->Data4[6], piid->Data4[7]);
return(s); }
#define MAX_LOGS 1024 * 1024
typedef struct _PTR_RECORD { PVOID ptrRecord; ULONG keySort; } PTR_RECORD, * PPTR_RECORD;
static PPTR_RECORD PtrBuffer = NULL; static ULONG PtrMax = MAX_LOGS; static ULONG PtrTotal = 0; static ULONG PtrIndex;
int __cdecl CompareFileRecord(const void * p1, const void * p2) { PPTR_RECORD pp1 = (PPTR_RECORD) p1; PPTR_RECORD pp2 = (PPTR_RECORD) p2; PFILE_RECORD pFile1 = (PFILE_RECORD) pp1->ptrRecord; PFILE_RECORD pFile2 = (PFILE_RECORD) pp2->ptrRecord;
LONG diffFault = pp2->keySort - pp1->keySort; if (diffFault == 0) { diffFault = pFile1->DiskNumber - pFile2->DiskNumber; if (diffFault == 0) { diffFault = wcscmp(pFile1->FileName, pFile2->FileName); } }
return diffFault; }
void ReportHotFileInfo() { PLIST_ENTRY pHead = & CurrentSystem.HotFileListHead; PLIST_ENTRY pNext = pHead->Flink; PFILE_RECORD pFile; BOOLEAN fDone = FALSE; ULONGLONG Duration = ((CurrentSystem.EndTime - CurrentSystem.StartTime) / 10000000); PMOF_INFO pMofInfo;
pMofInfo = GetMofInfoHead ((LPCGUID)&ProcessGuid); if ( pMofInfo == NULL ) { return; } pMofInfo = GetMofInfoHead ((LPCGUID)&ThreadGuid); if ( pMofInfo == NULL ) { return; }
ASSERT(!PtrBuffer); PtrBuffer = (PPTR_RECORD) VirtualAlloc( NULL, sizeof(PTR_RECORD) * PtrMax, MEM_COMMIT, PAGE_READWRITE); if( NULL == PtrBuffer ){ goto Cleanup; }
while (!fDone) { for (PtrTotal = 0, fDone = TRUE; pNext != pHead; pNext = pNext->Flink) { if (PtrTotal == PtrMax) { fDone = FALSE; break; }
pFile = CONTAINING_RECORD(pNext, FILE_RECORD, Entry);
if (pFile->ReadCount + pFile->WriteCount > 0) { PtrBuffer[PtrTotal].ptrRecord = (PVOID) pFile; PtrBuffer[PtrTotal].keySort = pFile->ReadCount + pFile->WriteCount; PtrTotal ++; } }
if (!fDone) { VirtualFree(PtrBuffer, 0, MEM_RELEASE); PtrMax += MAX_LOGS; PtrBuffer = (PPTR_RECORD) VirtualAlloc( NULL, sizeof(PTR_RECORD) * PtrMax, MEM_COMMIT, PAGE_READWRITE); if (PtrBuffer == NULL) { goto Cleanup; } } }
if (PtrTotal > 1) { qsort((void *) PtrBuffer, (size_t) PtrTotal, (size_t) sizeof(PTR_RECORD), CompareFileRecord); } else { return; }
if (PtrTotal > DISPLAY_SIZE) { PtrTotal = DISPLAY_SIZE; }
// output HotFile report title
//
fprintf( procFile, "<table title='Files Causing Most Disk IOs' top='%d'>\n", DISPLAY_SIZE );
for (PtrIndex = 0; PtrIndex < PtrTotal; PtrIndex ++) { PLIST_ENTRY pProtoHead; PLIST_ENTRY pProtoNext; PPROTO_PROCESS_RECORD pProto; WCHAR ReducedFileName[FILE_NAME_COLUMN_SIZE + 1]; LPWSTR szFile; PWCHAR szLongFile; LPWSTR szDrive = L"";
pFile = (PFILE_RECORD) PtrBuffer[PtrIndex].ptrRecord;
if (NULL != pFile->Drive) { szDrive = pFile->Drive; } if (_wcsnicmp(pFile->FileName, L"\\Device\\", 8) == 0) { szLongFile = (PWCHAR)(pFile->FileName) + 8; while (*szLongFile != L'\\' && *szLongFile != L'\0') { szLongFile++; } } else { szLongFile = (PWCHAR)(pFile->FileName); }
if (wcslen(szLongFile) > FILE_NAME_COLUMN_SIZE) { ReduceStringW(ReducedFileName, FILE_NAME_COLUMN_SIZE + 1, szLongFile); szFile = ReducedFileName; }else{ szFile = szLongFile; }
fprintf(procFile, "<file name='%ws'>" "<disk>%d</disk>" "<drive>%ws</drive>" "<read_rate>%1.3f</read_rate>" "<read_size>%d</read_size>" "<write_rate>%1.3f</write_rate>" "<write_size>%d</write_size>\n", szFile, pFile->DiskNumber, szDrive, Duration ? ((double)pFile->ReadCount / (double)Duration) : 0.0, (pFile->ReadCount) ? (pFile->ReadSize / pFile->ReadCount) : 0, Duration ? ((double)pFile->WriteCount / (double)Duration) : 0.0, (pFile->WriteCount) ? (pFile->WriteSize / pFile->WriteCount) : 0);
pProtoHead = & pFile->ProtoProcessListHead; pProtoNext = pProtoHead->Flink;
while (pProtoNext != pProtoHead) { pProto = CONTAINING_RECORD(pProtoNext, PROTO_PROCESS_RECORD, Entry); pProtoNext = pProtoNext->Flink;
if (pProto->ReadCount + pProto->WriteCount > 0) { fprintf(procFile, "<image name='%ws'>" "<pid>0x%08X</pid>" "<read_rate>%1.3f</read_rate>" "<read_size>%d</read_size>" "<write_rate>%1.3f</write_rate>" "<write_size>%d</write_size>" "</image>\n", pProto->ProcessRecord->ImageName, pProto->ProcessRecord->PID, Duration ? ((double)pProto->ReadCount / (double)Duration) : 0.0, (pProto->ReadCount) ? (pProto->ReadSize / pProto->ReadCount) : 0, Duration ? ((double)pProto->WriteCount / (double)Duration) : 0.0, (pProto->WriteCount) ? (pProto->WriteSize / pProto->WriteCount) : 0); } } fprintf( procFile, "</file>\n" ); }
fprintf( procFile, "</table>\n" );
Cleanup: if (PtrBuffer) { VirtualFree(PtrBuffer, 0, MEM_RELEASE); } }
#define CHECKTOK( x ) if( NULL == x ) { continue; }
static void ReportPrintJobInfo2(void) { PRINT_JOB_RECORD Job, *pJob; char* s; char line[MAXSTR];
ULONG TotalCount = 0; ULONGLONG TotalRT = 0; ULONG TotalCPUTime = 0;
pJob = &Job;
if( NULL == CurrentSystem.TempPrintFile ){ return; }
rewind( CurrentSystem.TempPrintFile );
while ( fgets(line, MAXSTR, CurrentSystem.TempPrintFile) != NULL ) { s = strtok( line, (",")); CHECKTOK( s ); pJob->JobId = atol(s); if (pJob == NULL){ return; } }
fprintf(procFile, "<table title='Spooler Transaction Instance (Job) Data'>\n");
RtlZeroMemory(pJob, sizeof(PRINT_JOB_RECORD)); RtlZeroMemory(line, MAXSTR * sizeof(char));
rewind( CurrentSystem.TempPrintFile );
while ( fgets(line, MAXSTR, CurrentSystem.TempPrintFile) != NULL ) { s = strtok( line, (",")); CHECKTOK( s ); pJob->JobId = atol(s); if (pJob == NULL){ continue; }
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->KCPUTime = atol(s); s = strtok( NULL, (",")); CHECKTOK( s ); pJob->UCPUTime = atol(s); s = strtok( NULL, (",")); CHECKTOK( s ); pJob->ReadIO = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->StartTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->EndTime = _atoi64(s); s = strtok( NULL, (",")); CHECKTOK( s ); pJob->ResponseTime = _atoi64(s); s = strtok( NULL, (",")); CHECKTOK( s ); pJob->PrintJobTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->WriteIO = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->DataType = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->JobSize = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->Pages = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->PagesPerSide = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->FilesOpened = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->GdiJobSize = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->Color = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->XRes = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->YRes = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->Quality = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->Copies = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->TTOption = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->NumberOfThreads = atol(s);
fprintf(procFile, "<job id='%d'>" "<type>%d</type>" "<size>%d</size>" "<pages>%d</pages>" "<PPS>%d</PPS>" "<files>%hd</files>" "<gdisize>%d</gdisize>" "<color>%hd</color>" "<xres>%hd</xres>" "<yres>%hd</yres>" "<qlty>%hd</qlty>" "<copies>%hd</copies>" "<ttopt>%hd</ttopt>" "<threads>%d</threads>" "</job>\n", pJob->JobId, pJob->DataType, ((pJob->JobSize) / 1024), pJob->Pages, pJob->PagesPerSide, pJob->FilesOpened, pJob->GdiJobSize, pJob->Color, pJob->XRes, pJob->YRes, pJob->Quality, pJob->Copies, pJob->TTOption, pJob->NumberOfThreads ); }
fprintf(procFile, "</table>\n" ); }
static void ReportPrintJobInfo(void) { PRINT_JOB_RECORD Job, *pJob; char* s; char line[MAXSTR];
FILETIME StTm, StlTm; LARGE_INTEGER LargeTmp; SYSTEMTIME stStart, stEnd, stDequeue;
ULONG TotalCount = 0; ULONGLONG TotalRT = 0; ULONG TotalCPUTime = 0;
if( NULL == CurrentSystem.TempPrintFile ){ return; }
pJob = &Job;
rewind( CurrentSystem.TempPrintFile );
while ( fgets(line, MAXSTR, CurrentSystem.TempPrintFile) != NULL ) { s = strtok( line, (",")); CHECKTOK( s ); pJob->JobId = atol(s); if (pJob == NULL){ return; } }
fprintf(procFile, "<table title='Transaction Instance (Job) Statistics'>\n" );
RtlZeroMemory(pJob, sizeof(PRINT_JOB_RECORD)); RtlZeroMemory(line, MAXSTR * sizeof(char));
rewind( CurrentSystem.TempPrintFile );
while ( fgets(line, MAXSTR, CurrentSystem.TempPrintFile) != NULL ) { s = strtok( line, (",")); CHECKTOK( s ); pJob->JobId = atol(s); if (pJob == NULL){ continue; }
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->KCPUTime = atol(s); s = strtok( NULL, (",")); CHECKTOK( s ); pJob->UCPUTime = atol(s); s = strtok( NULL, (",")); CHECKTOK( s ); pJob->ReadIO = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->StartTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->EndTime = _atoi64(s); s = strtok( NULL, (",")); CHECKTOK( s ); pJob->ResponseTime = _atoi64(s); s = strtok( NULL, (",")); CHECKTOK( s ); pJob->PrintJobTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->WriteIO = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->DataType = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->JobSize = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->Pages = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->PagesPerSide = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->FilesOpened = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->GdiJobSize = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->Color = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->XRes = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->YRes = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->Quality = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->Copies = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->TTOption = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pJob->NumberOfThreads = atol(s);
LargeTmp.QuadPart = pJob->StartTime; StTm.dwHighDateTime = LargeTmp.HighPart; StTm.dwLowDateTime = LargeTmp.LowPart; FileTimeToLocalFileTime(&StTm, &StlTm);
FileTimeToSystemTime ( &StlTm, &stStart );
LargeTmp.QuadPart = pJob->EndTime; StTm.dwHighDateTime = LargeTmp.HighPart; StTm.dwLowDateTime = LargeTmp.LowPart; FileTimeToLocalFileTime(&StTm, &StlTm);
FileTimeToSystemTime ( &StlTm, &stEnd );
LargeTmp.QuadPart = pJob->PrintJobTime; StTm.dwHighDateTime = LargeTmp.HighPart; StTm.dwLowDateTime = LargeTmp.LowPart; FileTimeToLocalFileTime(&StTm, &StlTm);
FileTimeToSystemTime ( &StlTm, &stDequeue );
fprintf(procFile, "<job id='%d'>" "<start>%2d:%02d:%02d.%03d</start>" "<dequeue>%2d:%02d:%02d.%03d</dequeue>" "<end>%2d:%02d:%02d.%03d</end>" "<response_time>%I64u</response_time>" "<cpu>%d</cpu>" "</job>\n", pJob->JobId, stStart.wHour, stStart.wMinute, stStart.wSecond, stStart.wMilliseconds, stDequeue.wHour, stDequeue.wMinute, stDequeue.wSecond, stDequeue.wMilliseconds, stEnd.wHour, stEnd.wMinute, stEnd.wSecond, stEnd.wMilliseconds, pJob->ResponseTime, pJob->KCPUTime + pJob->UCPUTime ); TotalCount++; TotalRT += pJob->ResponseTime; TotalCPUTime += (pJob->KCPUTime + pJob->UCPUTime); }
if (TotalCount > 0) { TotalRT /= TotalCount; TotalCPUTime /= TotalCount; }
fprintf(procFile, "<summary>" "<count>%d</count>" "<total_response_time>%I64u</total_response_time>" "<total_cpu>%d</total_cpu>" "</summary>\n", TotalCount, TotalRT, TotalCPUTime );
fprintf(procFile, "</table>\n" );
ReportPrintJobInfo2(); }
PUCHAR CopyUrlStr(PUCHAR UrlStr) { PUCHAR CopiedStr; if (UrlStr == NULL) { return NULL; } CopiedStr = (PUCHAR)malloc(strlen(UrlStr) + 1); if (CopiedStr != NULL) { RtlCopyMemory(CopiedStr, UrlStr, strlen(UrlStr) + 1); return CopiedStr; } else { return NULL; } }
void ProcessIisRequest(HTTP_REQUEST_RECORD *pReq) { // Global variable IIS must not be NULL here.
PURL_RECORD pUrl; PCLIENT_RECORD pClient; PSITE_RECORD pSite;
pUrl = FindOrAddUrlRecord(pReq->URL); if (pUrl != NULL) { pUrl->SiteId = pReq->SiteId; pUrl->Requests++; pUrl->TotalResponseTime += pReq->ULResponseTime; pUrl->KCPUTime += pReq->KCPUTime; pUrl->UCPUTime += pReq->UCPUTime; pUrl->ReadIO += pReq->ReadIO; pUrl->WriteIO += pReq->WriteIO; pUrl->BytesSent += pReq->BytesSent; // Cached responses don't have this field filled
// Thus need to check for Hits field as well
pUrl->UrlType = pReq->W3ProcessType; }
pClient = FindOrAddClientRecord(pReq->IpAddrType, pReq->IpAddrV4, pReq->IpAddrV6); if (pClient != NULL) { pClient->Requests++; pClient->TotalResponseTime += pReq->ULResponseTime; pClient->BytesSent += pReq->BytesSent; }
pSite = FindOrAddSiteRecord(pReq->SiteId); if (pSite != NULL) { pSite->Requests++; pSite->TotalResponseTime += pReq->ULResponseTime; pSite->KCPUTime += pReq->KCPUTime; pSite->UCPUTime += pReq->UCPUTime; pSite->ReadIO += pReq->ReadIO; pSite->WriteIO += pReq->WriteIO; pSite->BytesSent += pReq->BytesSent; }
if (pReq->ULEndType == EVENT_TRACE_TYPE_UL_CACHEDEND) { IIS->CachedResponses++; IIS->TotalCachedResponseTime += pReq->ULResponseTime; IIS->CachedCPUTime += pReq->KCPUTime + pReq->UCPUTime; if (pUrl != NULL) { pUrl->Hits++; } if (pClient != NULL) { pClient->Hits++; } if (pSite != NULL) { pSite->Hits++; } } else { ULONGLONG localCGIEndTime = pReq->CGIEndTime; ULONGLONG localISAPIEndTime = pReq->ISAPIEndTime; ULONGLONG localASPEndTime = pReq->ASPEndTime; ULONGLONG W3ResponseTime; #ifdef DBG
// we'll check the validity of HTTP Requests Here.
ULONGLONG ULSum = 0, W3Res = 0; if (pReq->ULDeliverTime == 0 || pReq->ULReceiveTime == 0) { TrctrDbgPrint(("TRACERPT Error Req: %I64u UL DeliverTime nad/or ReceiveTime not available, should throw this away.\n", pReq->RequestId)); } else { ULSum = (pReq->ULDeliverTime - pReq->ULStartTime) + (pReq->ULEndTime - pReq->ULReceiveTime); } if (pReq->W3StartTime == 0) { TrctrDbgPrint(("TRACERPT Error Req: %I64u W3 StartTime not available, should throw this away.\n", pReq->RequestId)); } if (pReq->W3EndTime == 0) { TrctrDbgPrint(("TRACERPT Warning Req: %I64u W3 EndTime not available.\n", pReq->RequestId)); } if (pReq->W3StartTime != 0 && pReq->W3EndTime != 0 && pReq->W3EndTime < pReq->W3StartTime) { TrctrDbgPrint(("TRACERPT Warning Req: %I64u W3 EndTime smaller than pReq->W3StartTime.\n", pReq->RequestId)); } if (ULSum != 0 && pReq->W3StartTime != 0 && pReq->W3EndTime != 0) { double ULRatio = 0.0; W3Res = pReq->W3EndTime - pReq->W3StartTime; ULRatio = (double)ULSum / (double)(pReq->ULResponseTime - W3Res); if (ULRatio < 0.5 || ULRatio > 2.0) { TrctrDbgPrint(("TRACERPT Warning Req: %I64u UL Ratio is unreal.\n", pReq->RequestId)); } } if (pReq->W3ProcessType == EVENT_TRACE_TYPE_W3CORE_CGIREQ) { if (pReq->CGIStartTime == 0) { TrctrDbgPrint(("TRACERPT Error Req: %I64u CGI StartTime not available, should throw this away.\n", pReq->RequestId)); } if (pReq->CGIEndTime == 0) { TrctrDbgPrint(("TRACERPT Warning Req: %I64u CGI EndTime not available.\n", pReq->RequestId)); if (pReq->W3EndTime != 0 && (pReq->CGIStartTime > pReq->W3EndTime)) { TrctrDbgPrint(("TRACERPT Warning Req: %I64u CGI StartTime > pReq->W3EndTime.\n", pReq->RequestId)); } else if (pReq->W3EndTime == 0 && (pReq->CGIStartTime > pReq->ULReceiveTime)) { TrctrDbgPrint(("TRACERPT Warning Req: %I64u CGI StartTime > pReq->ULReceiveTime.\n", pReq->RequestId)); } } } else if (pReq->W3ProcessType == EVENT_TRACE_TYPE_W3CORE_ISAPIREQ) { if (pReq->ISAPIStartTime == 0) { TrctrDbgPrint(("TRACERPT Error Req: %I64u ISAPI StartTime not available, should throw this away.\n", pReq->RequestId)); } if (pReq->ISAPIEndTime == 0) { TrctrDbgPrint(("TRACERPT Warning Req: %I64u ISAPI EndTime not available.\n", pReq->RequestId)); if (pReq->W3EndTime != 0 && (pReq->ISAPIStartTime > pReq->W3EndTime)) { TrctrDbgPrint(("TRACERPT Warning Req: %I64u ISAPI StartTime > pReq->W3EndTime.\n", pReq->RequestId)); } else if (pReq->W3EndTime == 0 && (pReq->ISAPIStartTime > pReq->ULReceiveTime)) { TrctrDbgPrint(("TRACERPT Warning Req: %I64u ISAPI StartTime > pReq->ULReceiveTime.\n", pReq->RequestId)); } } if (pReq->ASPStartTime == 0) { TrctrDbgPrint(("TRACERPT Warning Req: %I64u ASP StartTime not available.\n", pReq->RequestId)); } if (pReq->ASPEndTime == 0) { TrctrDbgPrint(("TRACERPT Warning Req: %I64u ASP EndTime not available.\n", pReq->RequestId)); if (pReq->ISAPIEndTime != 0 && (pReq->ASPStartTime > pReq->ISAPIEndTime)) { TrctrDbgPrint(("TRACERPT Warning Req: %I64u ASP StartTime > pReq->ISAPIEndTime.\n", pReq->RequestId)); } else if (pReq->W3EndTime != 0 && (pReq->ASPStartTime > pReq->W3EndTime)) { TrctrDbgPrint(("TRACERPT Warning Req: %I64u ASP StartTime > pReq->W3EndTime.\n", pReq->RequestId)); } else if (pReq->W3EndTime == 0 && (pReq->ASPStartTime > pReq->ULReceiveTime)) { TrctrDbgPrint(("TRACERPT Warning Req: %I64u ASP StartTime > pReq->ULReceiveTime.\n", pReq->RequestId)); } } } #endif
// Fix the time inconsistency in transactions
if (pReq->W3StartTime == 0 || (pReq->W3EndTime != 0 && pReq->W3EndTime < pReq->W3StartTime)) { RequestsDiscarded++; if (pReq->URL != NULL) { free(pReq->URL); } return; } if (pReq->W3EndTime == 0 || pReq->W3EndTime > pReq->ULReceiveTime) { pReq->W3EndTime = pReq->ULReceiveTime; if (pReq->W3EndTime == 0 || pReq->W3EndTime < pReq->W3StartTime) { RequestsDiscarded++; if (pReq->URL != NULL) { free(pReq->URL); } return; } } W3ResponseTime = pReq->W3EndTime - pReq->W3StartTime; if (W3ResponseTime < pReq->W3FilterResponseTime) { pReq->W3FilterResponseTime = W3ResponseTime; }
if (pReq->W3ProcessType == EVENT_TRACE_TYPE_W3CORE_CGIREQ) { if (pReq->CGIStartTime == 0) { RequestsDiscarded++; if (pReq->URL != NULL) { free(pReq->URL); } return; } else if (pReq->CGIEndTime == 0 || pReq->CGIEndTime > pReq->W3EndTime) { localCGIEndTime = pReq->W3EndTime; if (pReq->CGIStartTime > localCGIEndTime) { RequestsDiscarded++; if (pReq->URL != NULL) { free(pReq->URL); } return; } } else { localCGIEndTime = pReq->CGIEndTime; }
if (pReq->CGIStartTime < pReq->W3StartTime) { pReq->CGIStartTime = pReq->W3StartTime; } if (localCGIEndTime < pReq->CGIStartTime) { localCGIEndTime = pReq->CGIStartTime; } if ((pReq->W3FilterResponseTime + (localCGIEndTime - pReq->CGIStartTime)) > W3ResponseTime) { pReq->W3FilterResponseTime = W3ResponseTime - (localCGIEndTime - pReq->CGIStartTime); } } else if (pReq->W3ProcessType == EVENT_TRACE_TYPE_W3CORE_ISAPIREQ) { if (pReq->ISAPIStartTime == 0) { RequestsDiscarded++; if (pReq->URL != NULL) { free(pReq->URL); } return; } if (pReq->ISAPIEndTime == 0 || pReq->ISAPIEndTime > pReq->W3EndTime) { localISAPIEndTime = pReq->W3EndTime; if (pReq->ISAPIStartTime > localISAPIEndTime) { RequestsDiscarded++; if (pReq->URL != NULL) { free(pReq->URL); } return; } } else { localISAPIEndTime = pReq->ISAPIEndTime; }
if (pReq->ISAPIStartTime < pReq->W3StartTime) { pReq->ISAPIStartTime = pReq->W3StartTime; } if (localISAPIEndTime < pReq->ISAPIStartTime) { localISAPIEndTime = pReq->ISAPIStartTime; } if ((pReq->W3FilterResponseTime + (localISAPIEndTime - pReq->ISAPIStartTime)) > W3ResponseTime) { pReq->W3FilterResponseTime = W3ResponseTime - (localISAPIEndTime - pReq->ISAPIStartTime); }
if (pReq->ASPStartTime != 0) { if (pReq->ASPEndTime == 0) { localASPEndTime = localISAPIEndTime; if (pReq->ASPStartTime > localASPEndTime) { RequestsDiscarded++; if (pReq->URL != NULL) { free(pReq->URL); } return; } } else { localASPEndTime = pReq->ASPEndTime; }
if (pReq->ASPStartTime < pReq->ISAPIStartTime) { pReq->ASPStartTime = pReq->ISAPIStartTime; } if (localASPEndTime < pReq->ASPStartTime) { localASPEndTime = pReq->ASPStartTime; } if ((localISAPIEndTime - pReq->ISAPIStartTime) < (localASPEndTime - pReq->ASPStartTime)) { localASPEndTime = localISAPIEndTime; } } } // Fix done. All end times are fixed.
IIS->TotalNonCachedResponseTime += pReq->ULResponseTime; IIS->NonCachedCPUTime += pReq->KCPUTime + pReq->UCPUTime;
if (pReq->W3FilterResponseTime != 0) { IIS->W3FilterRequests += pReq->W3FilterVisits; IIS->TotalW3FilterResponseTime += pReq->W3FilterResponseTime; IIS->TotalW3FilterCPUTime += pReq->W3FltrCPUTime; } if (pReq->ULEndType == EVENT_TRACE_TYPE_UL_SENDERROR && pReq->ISAPIStartTime == 0) { // This is a request ended with SENDERROR.
SendErrorRequests++; } if (pReq->HttpStatus != 0 && pReq->HttpStatus >= 400) { // This is a request with http error.
IIS->W3Error++; IIS->TotalErrorResponseTime += pReq->ULResponseTime; IIS->ErrorCPUTime += pReq->KCPUTime + pReq->UCPUTime; IIS->TotalErrorULOnlyCPUTime += pReq->ULCPUTime; IIS->TotalErrorW3OnlyCPUTime += pReq->W3CPUTime; IIS->TotalErrorW3FilterCPUTime += pReq->W3FltrCPUTime; IIS->TotalErrorCGIOnlyCPUTime += pReq->CGICPUTime; IIS->TotalErrorISAPIOnlyCPUTime += pReq->ISAPICPUTime; IIS->TotalErrorASPOnlyCPUTime += pReq->ASPCPUTime;
IIS->TotalErrorW3OnlyResponseTime += (pReq->W3EndTime - pReq->W3StartTime) - pReq->W3FilterResponseTime; if (pReq->ULStartTime != 0 && pReq->ULEndTime != 0 && pReq->ULDeliverTime != 0 && pReq->ULReceiveTime != 0) { // ????????????????????????????????????????????????????????????????????????
// TotalErrorULOnlyResponseTime += (pReq->ULDeliverTime - pReq->ULStartTime)
// + (pReq->ULEndTime - pReq->ULReceiveTime);
IIS->TotalErrorULOnlyResponseTime += pReq->ULResponseTime - (pReq->W3EndTime - pReq->W3StartTime); } else { IIS->TotalErrorULOnlyResponseTime += pReq->ULResponseTime - (pReq->W3EndTime - pReq->W3StartTime); } IIS->TotalErrorW3FilterResponseTime += pReq->W3FilterResponseTime; } else if (pReq->W3ProcessType == EVENT_TRACE_TYPE_W3CORE_FILEREQ) { IIS->W3FileRequests++; IIS->TotalFileResponseTime += pReq->ULResponseTime; IIS->FileCPUTime += pReq->KCPUTime + pReq->UCPUTime; IIS->TotalFileULOnlyCPUTime += pReq->ULCPUTime; IIS->TotalFileW3OnlyCPUTime += pReq->W3CPUTime; IIS->TotalFileW3FilterCPUTime += pReq->W3FltrCPUTime; if (pSite != NULL) { pSite->FileRequests++; } IIS->TotalFileW3OnlyResponseTime += (pReq->W3EndTime - pReq->W3StartTime) - pReq->W3FilterResponseTime; if (pReq->ULStartTime != 0 && pReq->ULEndTime != 0 && pReq->ULDeliverTime != 0 && pReq->ULReceiveTime != 0) { // ????????????????????????????????????????????????????????????????????????
// TotalFileULOnlyResponseTime += (pReq->ULDeliverTime - pReq->ULStartTime)
// + (pReq->ULEndTime - pReq->ULReceiveTime);
IIS->TotalFileULOnlyResponseTime += pReq->ULResponseTime - (pReq->W3EndTime - pReq->W3StartTime); } else { IIS->TotalFileULOnlyResponseTime += pReq->ULResponseTime - (pReq->W3EndTime - pReq->W3StartTime); } IIS->TotalFileW3FilterResponseTime += pReq->W3FilterResponseTime; } else if (pReq->W3ProcessType == EVENT_TRACE_TYPE_W3CORE_CGIREQ) { IIS->W3CGIRequests++; IIS->TotalCGIResponseTime += pReq->ULResponseTime; IIS->TotalCGIOnlyResponseTime += (localCGIEndTime - pReq->CGIStartTime); IIS->CGICPUTime += pReq->KCPUTime + pReq->UCPUTime; IIS->TotalCGIOnlyCPUTime += pReq->CGICPUTime; IIS->TotalCGIULOnlyCPUTime += pReq->ULCPUTime; IIS->TotalCGIW3OnlyCPUTime += pReq->W3CPUTime; IIS->TotalCGIW3FilterCPUTime += pReq->W3FltrCPUTime; if (pSite != NULL) { pSite->CGIRequests++; } IIS->TotalCGIW3OnlyResponseTime += (pReq->W3EndTime - pReq->W3StartTime) - (localCGIEndTime - pReq->CGIStartTime) - pReq->W3FilterResponseTime; if (pReq->ULStartTime != 0 && pReq->ULEndTime != 0 && pReq->ULDeliverTime != 0 && pReq->ULReceiveTime != 0) { // ????????????????????????????????????????????????????????????????????????
// TotalCGIULOnlyResponseTime += (pReq->ULDeliverTime - pReq->ULStartTime)
// + (pReq->ULEndTime - pReq->ULReceiveTime);
IIS->TotalCGIULOnlyResponseTime += pReq->ULResponseTime - (pReq->W3EndTime - pReq->W3StartTime); } else { IIS->TotalCGIULOnlyResponseTime += pReq->ULResponseTime - (pReq->W3EndTime - pReq->W3StartTime); } IIS->TotalCGIW3FilterResponseTime += pReq->W3FilterResponseTime; } else if (pReq->W3ProcessType == EVENT_TRACE_TYPE_W3CORE_ISAPIREQ) { ULONGLONG TimeSpentInAsp = 0; ULONGLONG TimeSpentInISAPI = 0;
if (pReq->ASPStartTime != 0 && localASPEndTime != 0) { TimeSpentInAsp = localASPEndTime - pReq->ASPStartTime; } if (pReq->ISAPIStartTime != 0 && localISAPIEndTime != 0) { TimeSpentInISAPI = localISAPIEndTime - pReq->ISAPIStartTime; if (TimeSpentInAsp > TimeSpentInISAPI) { TimeSpentInISAPI = 0; } else { TimeSpentInISAPI -= TimeSpentInAsp; } }
IIS->W3ISAPIRequests++; IIS->TotalISAPIResponseTime += pReq->ULResponseTime; IIS->ISAPICPUTime += pReq->KCPUTime + pReq->UCPUTime; if (pSite != NULL) { pSite->ISAPIRequests++; } IIS->TotalASPW3OnlyResponseTime += (((pReq->W3EndTime - pReq->W3StartTime) - pReq->W3FilterResponseTime) - (TimeSpentInISAPI + TimeSpentInAsp)); IIS->W3ASPRequests++; IIS->TotalASPResponseTime += pReq->ULResponseTime; IIS->TotalASPOnlyResponseTime += TimeSpentInAsp; IIS->ASPCPUTime += pReq->KCPUTime + pReq->UCPUTime; IIS->TotalASPOnlyCPUTime += pReq->ASPCPUTime; IIS->TotalASPULOnlyCPUTime += pReq->ULCPUTime; IIS->TotalASPW3OnlyCPUTime += pReq->W3CPUTime; IIS->TotalASPW3FilterCPUTime += pReq->W3FltrCPUTime; IIS->TotalASPISAPIOnlyCPUTime += pReq->ISAPICPUTime; if (pSite != NULL) { pSite->ASPRequests++; } IIS->TotalASPISAPIOnlyResponseTime += TimeSpentInISAPI; if (pReq->ULStartTime != 0 && pReq->ULEndTime != 0 && pReq->ULDeliverTime != 0 && pReq->ULReceiveTime != 0) { // ????????????????????????????????????????????????????????????????????????
// TotalASPULOnlyResponseTime += (pReq->ULDeliverTime - pReq->ULStartTime)
// + (pReq->ULEndTime - pReq->ULReceiveTime);
IIS->TotalASPULOnlyResponseTime += pReq->ULResponseTime - (pReq->W3EndTime - pReq->W3StartTime); } else { IIS->TotalASPULOnlyResponseTime += pReq->ULResponseTime - (pReq->W3EndTime - pReq->W3StartTime); } IIS->TotalASPW3FilterResponseTime += pReq->W3FilterResponseTime; } else if (pReq->W3ProcessType == EVENT_TRACE_TYPE_W3CORE_OOPREQ) { // ???
IIS->W3OOPRequests++; IIS->TotalOOPResponseTime += pReq->ULResponseTime; IIS->OOPCPUTime += pReq->KCPUTime + pReq->UCPUTime; if (pSite != NULL) { pSite->OOPRequests++; } } }
IIS->TotalRequests++; IIS->TotalCPUTime += pReq->KCPUTime + pReq->UCPUTime;
if (pReq->URL != NULL) { free(pReq->URL); } }
static void ReportIisEvents(void) { HTTP_REQUEST_RECORD Req, *pReq; char* s; char line[MAXSTR];
URL_RECORD TopHitURLs[DISPLAY_SIZE]; URL_RECORD TopHitStaticURLs[DISPLAY_SIZE]; URL_RECORD TopSlowURLs[DISPLAY_SIZE]; URL_RECORD TopConsumingURLs[DISPLAY_SIZE]; URL_RECORD TopBytesURLs[DISPLAY_SIZE]; PURL_RECORD pUrl;
CLIENT_RECORD TopHitClients[DISPLAY_SIZE]; CLIENT_RECORD TopSlowClients[DISPLAY_SIZE]; CLIENT_RECORD TopBytesClients[DISPLAY_SIZE]; PCLIENT_RECORD pClient;
SITE_RECORD TopHitSites[DISPLAY_SIZE]; SITE_RECORD TopSlowSites[DISPLAY_SIZE]; SITE_RECORD TopConsumingSites[DISPLAY_SIZE]; SITE_RECORD TopBytesSites[DISPLAY_SIZE]; PSITE_RECORD pSite;
ULONG i, k; ULONG Duration = (ULONG)((CurrentSystem.IISEndTime - CurrentSystem.IISStartTime) / 10000000); ULONG MilDuration = (ULONG)((CurrentSystem.IISEndTime - CurrentSystem.IISStartTime) * CurrentSystem.NumberOfProcessors / 10000); double Rates = 0.0; PLIST_ENTRY Next, Head; ULONG PrintCPUUsage = TRUE;
if( NULL == CurrentSystem.TempIisFile ){ return; }
IIS = (PIIS_REPORT_RECORD)malloc(sizeof(IIS_REPORT_RECORD)); if (IIS == NULL) { return; } RtlZeroMemory(IIS, sizeof(IIS_REPORT_RECORD));
Head = &CurrentSystem.ProcessListHead; Next = Head->Flink; if( Head == Next ){ PrintCPUUsage = FALSE; }
pReq = &Req;
RtlZeroMemory(pReq, sizeof(HTTP_REQUEST_RECORD)); RtlZeroMemory(line, MAXSTR * sizeof(char));
// Process requests written in the file
rewind( CurrentSystem.TempIisFile ); while ( fgets(line, MAXSTR, CurrentSystem.TempIisFile) != NULL ) { s = strtok( line, (",")); CHECKTOK( s ); pReq->RequestId = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->SiteId = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->KCPUTime = atol(s); s = strtok( NULL, (",")); CHECKTOK( s ); pReq->UCPUTime = atol(s); s = strtok( NULL, (",")); CHECKTOK( s ); pReq->ReadIO = atol(s); s = strtok( NULL, (",")); CHECKTOK( s ); pReq->WriteIO = atol(s); s = strtok( NULL, (",")); CHECKTOK( s ); pReq->ULStartTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->ULEndTime = _atoi64(s); s = strtok( NULL, (",")); CHECKTOK( s ); pReq->ULResponseTime = _atoi64(s); s = strtok( NULL, (",")); CHECKTOK( s ); pReq->ULParseTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->ULDeliverTime = _atoi64(s); s = strtok( NULL, (",")); CHECKTOK( s ); pReq->ULReceiveTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->ULReceiveType = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->ULEndType = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->W3StartTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->W3EndTime = _atoi64(s); s = strtok( NULL, (",")); CHECKTOK( s ); pReq->W3FilterResponseTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->W3ProcessType = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->W3EndType = (SHORT) atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->FileReqTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->CGIStartTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->CGIEndTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->ISAPIStartTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->ISAPIEndTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->ASPStartTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->ASPEndTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->SSLResponseTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->StrmFltrResponseTime = _atoi64(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->HttpStatus = (USHORT) atol(s);; s = strtok( NULL, (",")); CHECKTOK( s ); pReq->IsapiExt = (USHORT) atol(s);; s = strtok( NULL, (",")); CHECKTOK( s ); pReq->IpAddrType = (USHORT) atol(s);;
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->IpAddrV4 = atol(s); s = strtok( NULL, (",")); CHECKTOK( s ); pReq->IpAddrV6[0] = (USHORT) atol(s);; s = strtok( NULL, (",")); CHECKTOK( s ); pReq->IpAddrV6[1] = (USHORT) atol(s);; s = strtok( NULL, (",")); CHECKTOK( s ); pReq->IpAddrV6[2] = (USHORT) atol(s);; s = strtok( NULL, (",")); CHECKTOK( s ); pReq->IpAddrV6[3] = (USHORT) atol(s);; s = strtok( NULL, (",")); CHECKTOK( s ); pReq->IpAddrV6[4] = (USHORT) atol(s);; s = strtok( NULL, (",")); CHECKTOK( s ); pReq->IpAddrV6[5] = (USHORT) atol(s);; s = strtok( NULL, (",")); CHECKTOK( s ); pReq->IpAddrV6[6] = (USHORT) atol(s);; s = strtok( NULL, (",")); CHECKTOK( s ); pReq->IpAddrV6[7] = (USHORT) atol(s);; s = strtok( NULL, (",")); CHECKTOK( s ); pReq->NumberOfThreads = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->BytesSent = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->ULCPUTime = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->W3CPUTime = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->W3FltrCPUTime = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->ISAPICPUTime = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->ASPCPUTime = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); pReq->CGICPUTime = atol(s);
s = strtok( NULL, (",")); CHECKTOK( s ); if (strlen(s) > 0) { LPSTR strptr = (LPSTR)malloc(strlen(s) + 1); if (strptr != NULL) { RtlCopyMemory((PUCHAR)strptr, (PUCHAR)s, strlen(s)); if (*(strptr + strlen(s) - 1) == '\n') { *(strptr + strlen(s) - 1) = '\0'; } else { *(strptr + strlen(s)) = '\0'; } pReq->URL = (PCHAR)strptr; } else { continue; } } else { continue; }
ProcessIisRequest(pReq);
}
if (IIS->TotalRequests != 0) { if (Duration != 0) { Rates = (double)(IIS->TotalRequests) / (double)Duration; } else { Rates = 0.0; } } else { free(IIS); return; }
fprintf(procFile, "<table title='Http Requests Response Time Statistics'>\n"); fprintf(procFile, "<requests cached='true' type='Static HTTP'>" "<rate>%1.3f</rate>" "<response_time>%1.3f</response_time>" "<component name='UL'>%3d.0</component>" "<component name='W3'>0.0</component>" "<component name='W3Fltr'>0.0</component>" "<component name='ISAPI'>0.0</component>" "<component name='ASP'>0.0</component>" "<component name='CGI'>0.0</component>" "</requests>\n", Duration ? (double)(IIS->CachedResponses) / (double)Duration : 0.0, IIS->CachedResponses ? (double)(IIS->TotalCachedResponseTime / IIS->CachedResponses) / 10000.0 : 0.0, IIS->CachedResponses ? 100 : 0); fprintf(procFile, "<requests cached='false' type='ASP'>" "<rate>%1.3f</rate>" "<response_time>%1.3f</response_time>" "<component name='UL'>%1.1f</component>" "<component name='W3'>%1.1f</component>" "<component name='W3Fltr'>%1.1f</component>" "<component name='ISAPI'>%1.1f</component>" "<component name='ASP'>%1.1f</component>" "<component name='CGI'>%1.1f</component>" "</requests>\n", Duration ? (double)(IIS->W3ISAPIRequests) / (double)Duration : 0.0, (IIS->W3ISAPIRequests) ? ((double)IIS->TotalISAPIResponseTime / (double)IIS->W3ISAPIRequests) / 10000.0 : 0.0, ((IIS->TotalASPResponseTime) ? ((double)(IIS->TotalASPULOnlyResponseTime) / (double)(IIS->TotalASPResponseTime)) * 100.0 : 0.0), ((IIS->TotalASPResponseTime) ? ((double)(IIS->TotalASPW3OnlyResponseTime) / (double)(IIS->TotalASPResponseTime)) * 100.0 : 0.0), ((IIS->TotalASPResponseTime) ? ((double)(IIS->TotalASPW3FilterResponseTime) / (double)(IIS->TotalASPResponseTime)) * 100.0 : 0.0), ((IIS->TotalASPResponseTime) ? ((double)(IIS->TotalASPISAPIOnlyResponseTime) / (double)(IIS->TotalASPResponseTime)) * 100.0 : 0.0), ((IIS->TotalASPResponseTime) ? ((double)(IIS->TotalASPOnlyResponseTime) / (double)(IIS->TotalASPResponseTime)) * 100.0 : 0.0), 0.0); fprintf(procFile, "<requests cached='false' type='Static HTTP'>" "<rate>%1.3f</rate>" "<response_time>%1.3f</response_time>" "<component name='UL'>%1.1f</component>" "<component name='W3'>%1.1f</component>" "<component name='W3Fltr'>%1.1f</component>" "<component name='ISAPI'>%1.1f</component>" "<component name='ASP'>%1.1f</component>" "<component name='CGI'>%1.1f</component>" "</requests>\n", Duration ? (double)(IIS->W3FileRequests) / (double)Duration : 0.0, (IIS->W3FileRequests) ? ((double)IIS->TotalFileResponseTime / (double)IIS->W3FileRequests) / 10000.0 : 0.0, (IIS->TotalFileResponseTime ? ((double)(IIS->TotalFileULOnlyResponseTime) / (double)(IIS->TotalFileResponseTime)) * 100.0 : 0.0), (IIS->TotalFileResponseTime ? ((double)(IIS->TotalFileW3OnlyResponseTime) / (double)(IIS->TotalFileResponseTime)) * 100.0 : 0.0), (IIS->TotalFileResponseTime ? ((double)(IIS->TotalFileW3FilterResponseTime) / (double)(IIS->TotalFileResponseTime)) * 100.0 : 0.0), 0.0, 0.0, 0.0); fprintf(procFile, "<requests cached='false' type='CGI'>" "<rate>%1.3f</rate>" "<response_time>%1.3f</response_time>" "<component name='UL'>%1.1f</component>" "<component name='W3'>%1.1f</component>" "<component name='W3Fltr'>%1.1f</component>" "<component name='ISAPI'>%1.1f</component>" "<component name='ASP'>%1.1f</component>" "<component name='CGI'>%1.1f</component>" "</requests>\n", Duration ? (double)(IIS->W3CGIRequests) / (double)Duration : 0.0, (IIS->W3CGIRequests) ? ((double)IIS->TotalCGIResponseTime / (double)IIS->W3CGIRequests) / 10000.0 : 0.0, ((IIS->TotalCGIResponseTime) ? ((double)(IIS->TotalCGIULOnlyResponseTime) / (double)(IIS->TotalCGIResponseTime)) * 100.0 : 0.0), ((IIS->TotalCGIResponseTime) ? ((double)(IIS->TotalCGIW3OnlyResponseTime) / (double)(IIS->TotalCGIResponseTime)) * 100.0 : 0.0), ((IIS->TotalCGIResponseTime) ? ((double)(IIS->TotalCGIW3FilterResponseTime) / (double)(IIS->TotalCGIResponseTime)) * 100.0 : 0.0), 0.0, 0.0, ((IIS->TotalCGIResponseTime) ? ((double)(IIS->TotalCGIOnlyResponseTime) / (double)(IIS->TotalCGIResponseTime)) * 100.0 : 0.0));
if (IIS->W3Error != 0) { fprintf(procFile, "<requests cached='false' type='Error'>" "<rate>%1.3f</rate>" "<response_time>%1.3f</response_time>" "<component name='UL'>%1.1f</component>" "<component name='W3'>%1.1f</component>" "<component name='W3Fltr'>%1.1f</component>" "<component name='ISAPI'>%1.1f</component>" "<component name='ASP'>%1.1f</component>" "<component name='CGI'>%1.1f</component>" "</requests>\n", Duration ? (double)(IIS->W3Error) / (double)Duration : 0.0, (IIS->W3Error) ? ((double)IIS->TotalErrorResponseTime / (double)IIS->W3Error) / 10000.0 : 0.0, ((IIS->TotalErrorResponseTime) ? ((double)(IIS->TotalErrorULOnlyResponseTime) / (double)(IIS->TotalErrorResponseTime)) * 100.0 : 0.0), ((IIS->TotalErrorResponseTime) ? ((double)(IIS->TotalErrorW3OnlyResponseTime) / (double)(IIS->TotalErrorResponseTime)) * 100.0 : 0.0), ((IIS->TotalErrorResponseTime) ? ((double)(IIS->TotalErrorW3FilterResponseTime) / (double)(IIS->TotalErrorResponseTime)) * 100.0 : 0.0), 0.0, 0.0, 0.0); }
fprintf(procFile, "<summary cached='true'>" "<rate>%1.3f</rate>" "<response_time>%1.3f</response_time>" "<component name='UL'>%3d.0</component>" "<component name='W3'>0.0</component>" "<component name='W3Fltr'>0.0</component>" "<component name='ISAPI'>0.0</component>" "<component name='ASP'>0.0</component>" "<component name='CGI'>0.0</component>" "</summary>\n", Duration ? (double)(IIS->CachedResponses) / (double)Duration : 0.0, IIS->CachedResponses ? (double)(IIS->TotalCachedResponseTime / IIS->CachedResponses) / 10000.0 : 0.0, IIS->CachedResponses ? 100 : 0);
fprintf(procFile, "<summary cached='false'>" "<rate percent='%1.3f'>%1.3f</rate>" "<response_time>%1.3f</response_time>" "<component name='UL'>%1.1f</component>" "<component name='W3'>%1.1f</component>" "<component name='W3Fltr'>%1.1f</component>" "<component name='ISAPI'>%1.1f</component>" "<component name='ASP'>%1.1f</component>" "<component name='CGI'>%1.1f</component>" "</summary>\n", ((double)(IIS->TotalRequests - IIS->CachedResponses) / ((double)IIS->TotalRequests)) * 100.0, Duration ? (double)(IIS->TotalRequests - IIS->CachedResponses) / (double)Duration : 0.0, (IIS->TotalRequests - IIS->CachedResponses) ? ((double)IIS->TotalNonCachedResponseTime / (double)(IIS->TotalRequests - IIS->CachedResponses)) / 10000.0 : 0.0, ((IIS->TotalNonCachedResponseTime) ? ((double)(IIS->TotalFileULOnlyResponseTime + IIS->TotalCGIULOnlyResponseTime + IIS->TotalASPULOnlyResponseTime + IIS->TotalErrorULOnlyResponseTime) / (double)(IIS->TotalNonCachedResponseTime)) * 100.0 : 0.0), ((IIS->TotalNonCachedResponseTime) ? ((double)(IIS->TotalFileW3OnlyResponseTime + IIS->TotalCGIW3OnlyResponseTime + IIS->TotalASPW3OnlyResponseTime + IIS->TotalErrorW3OnlyResponseTime) / (double)(IIS->TotalNonCachedResponseTime)) * 100.0 : 0.0), ((IIS->TotalNonCachedResponseTime) ? ((double)(IIS->TotalW3FilterResponseTime) / (double)(IIS->TotalNonCachedResponseTime)) * 100.0 : 0.0), ((IIS->TotalNonCachedResponseTime) ? ((double)(IIS->TotalASPISAPIOnlyResponseTime) / (double)(IIS->TotalNonCachedResponseTime)) * 100.0 : 0.0), ((IIS->TotalNonCachedResponseTime) ? ((double)(IIS->TotalASPOnlyResponseTime) / (double)(IIS->TotalNonCachedResponseTime)) * 100.0: 0.0), ((IIS->TotalNonCachedResponseTime) ? ((double)(IIS->TotalCGIOnlyResponseTime) / (double)(IIS->TotalNonCachedResponseTime)) * 100.0: 0.0));
fprintf(procFile, "<summary type='totals'>" "<rate>%1.3f</rate>" "<response_time>%1.3f</response_time>" "<component name='UL'>%1.1f</component>" "<component name='W3'>%1.1f</component>" "<component name='W3Fltr'>%1.1f</component>" "<component name='ISAPI'>%1.1f</component>" "<component name='ASP'>%1.1f</component>" "<component name='CGI'>%1.1f</component>" "</summary>\n", Duration ? (double)(IIS->TotalRequests) / (double)Duration : 0.0, ((double)(IIS->TotalCachedResponseTime + IIS->TotalNonCachedResponseTime) / (double)IIS->TotalRequests) / 10000.0, ((IIS->TotalCachedResponseTime + IIS->TotalNonCachedResponseTime) ? ((double)(IIS->TotalCachedResponseTime + IIS->TotalFileULOnlyResponseTime + IIS->TotalCGIULOnlyResponseTime + IIS->TotalASPULOnlyResponseTime + IIS->TotalErrorULOnlyResponseTime) / (double)(IIS->TotalCachedResponseTime + IIS->TotalNonCachedResponseTime)) * 100.0 : 0.0), ((IIS->TotalCachedResponseTime + IIS->TotalNonCachedResponseTime) ? ((double)(IIS->TotalFileW3OnlyResponseTime + IIS->TotalCGIW3OnlyResponseTime + IIS->TotalASPW3OnlyResponseTime + IIS->TotalErrorW3OnlyResponseTime) / (double)(IIS->TotalCachedResponseTime + IIS->TotalNonCachedResponseTime)) * 100.0 : 0.0), ((IIS->TotalCachedResponseTime + IIS->TotalNonCachedResponseTime) ? ((double)(IIS->TotalW3FilterResponseTime) / (double)(IIS->TotalCachedResponseTime + IIS->TotalNonCachedResponseTime)) * 100.0 : 0.0), ((IIS->TotalCachedResponseTime + IIS->TotalNonCachedResponseTime) ? ((double)(IIS->TotalASPISAPIOnlyResponseTime) / (double)(IIS->TotalCachedResponseTime + IIS->TotalNonCachedResponseTime)) * 100.0 : 0.0), ((IIS->TotalCachedResponseTime + IIS->TotalNonCachedResponseTime) ? ((double)(IIS->TotalASPOnlyResponseTime) / (double)(IIS->TotalCachedResponseTime + IIS->TotalNonCachedResponseTime)) * 100.0 : 0.0), ((IIS->TotalCachedResponseTime + IIS->TotalNonCachedResponseTime) ? ((double)(IIS->TotalCGIOnlyResponseTime) / (double)(IIS->TotalCachedResponseTime + IIS->TotalNonCachedResponseTime)) * 100.0 : 0.0)); fprintf(procFile, "</table>\n");
if (PrintCPUUsage) { fprintf(procFile, "<table title='Http Requests CPU Time Usage Statistics'>\n"); fprintf(procFile, "<requests cached='true' type='Static HTTP'>" "<rate>%1.3f</rate>" "<cpu>%1.1f</cpu>" "<component name='UL'>%3d.0</component>" "<component name='W3'>0.0</component>" "<component name='W3Fltr'>0.0</component>" "<component name='ISAPI'>0.0</component>" "<component name='ASP'>0.0</component>" "<component name='CGI'>0.0</component>" "</requests>\n", Duration ? (double)(IIS->CachedResponses) / (double)Duration : 0.0, MilDuration ? (((double)(IIS->CachedCPUTime) / (double)MilDuration) * 100.0) : 0.0, IIS->CachedResponses ? 100 : 0); fprintf(procFile, "<requests cached='false' type='ASP'>" "<rate>%1.3f</rate>" "<cpu>%1.1f</cpu>" "<component name='UL'>%1.1f</component>" "<component name='W3'>%1.1f</component>" "<component name='W3Fltr'>%1.1f</component>" "<component name='ISAPI'>%1.1f</component>" "<component name='ASP'>%1.1f</component>" "<component name='CGI'>%1.1f</component>" "</requests>\n", Duration ? (double)(IIS->W3ISAPIRequests) / (double)Duration : 0.0, MilDuration ? (((double)(IIS->ISAPICPUTime) / (double)MilDuration) * 100.0) : 0.0, ((IIS->ASPCPUTime) ? ((double)(IIS->TotalASPULOnlyCPUTime) / (double)(IIS->ASPCPUTime)) * 100.0 : 0.0), ((IIS->ASPCPUTime) ? ((double)(IIS->TotalASPW3OnlyCPUTime) / (double)(IIS->ASPCPUTime)) * 100.0 : 0.0), ((IIS->ASPCPUTime) ? ((double)(IIS->TotalASPW3FilterCPUTime) / (double)(IIS->ASPCPUTime)) * 100.0 : 0.0), ((IIS->ASPCPUTime) ? ((double)(IIS->TotalASPISAPIOnlyCPUTime) / (double)(IIS->ASPCPUTime)) * 100.0 : 0.0), ((IIS->ASPCPUTime) ? ((double)(IIS->TotalASPOnlyCPUTime) / (double)(IIS->ASPCPUTime)) * 100.0: 0.0), 0.0); fprintf(procFile, "<requests cached='false' type='Static HTTP'>" "<rate>%1.3f</rate>" "<cpu>%1.1f</cpu>" "<component name='UL'>%1.1f</component>" "<component name='W3'>%1.1f</component>" "<component name='W3Fltr'>%1.1f</component>" "<component name='ISAPI'>%1.1f</component>" "<component name='ASP'>%1.1f</component>" "<component name='CGI'>%1.1f</component>" "</requests>\n", Duration ? (double)(IIS->W3FileRequests) / (double)Duration : 0.0, MilDuration ? (((double)(IIS->FileCPUTime) / (double)MilDuration) * 100.0) : 0.0, ((IIS->FileCPUTime) ? ((double)(IIS->TotalFileULOnlyCPUTime) / (double)(IIS->FileCPUTime)) * 100.0 : 0.0), ((IIS->FileCPUTime) ? ((double)(IIS->TotalFileW3OnlyCPUTime) / (double)(IIS->FileCPUTime)) * 100.0 : 0.0), ((IIS->FileCPUTime) ? ((double)(IIS->TotalFileW3FilterCPUTime) / (double)(IIS->FileCPUTime)) * 100.0 : 0.0), 0.0, 0.0, 0.0); fprintf(procFile, "<requests cached='false' type='CGI'>" "<rate>%1.3f</rate>" "<cpu>%1.1f</cpu>" "<component name='UL'>%1.1f</component>" "<component name='W3'>%1.1f</component>" "<component name='W3Fltr'>%1.1f</component>" "<component name='ISAPI'>%1.1f</component>" "<component name='ASP'>%1.1f</component>" "<component name='CGI'>%1.1f</component>" "</requests>\n", Duration ? (double)(IIS->W3CGIRequests) / (double)Duration : 0.0, MilDuration ? (((double)(IIS->CGICPUTime) / (double)MilDuration) * 100.0) : 0.0, ((IIS->CGICPUTime) ? ((double)(IIS->TotalCGIULOnlyCPUTime) / (double)(IIS->CGICPUTime)) * 100.0 : 0.0), ((IIS->CGICPUTime) ? ((double)(IIS->TotalCGIW3OnlyCPUTime) / (double)(IIS->CGICPUTime)) * 100.0 : 0.0), ((IIS->CGICPUTime) ? ((double)(IIS->TotalCGIW3FilterCPUTime) / (double)(IIS->CGICPUTime)) * 100.0 : 0.0), 0.0, 0.0, ((IIS->CGICPUTime) ? ((double)(IIS->TotalCGIOnlyCPUTime) / (double)(IIS->CGICPUTime)) * 100.0 : 0.0));
if (IIS->W3Error != 0) { fprintf(procFile, "<requests cached='false' type='Error'>" "<rate>%1.3f</rate>" "<cpu>%1.1f</cpu>" "<component name='UL'>%1.1f</component>" "<component name='W3'>%1.1f</component>" "<component name='W3Fltr'>%1.1f</component>" "<component name='ISAPI'>%1.1f</component>" "<component name='ASP'>%1.1f</component>" "<component name='CGI'>%1.1f</component>" "</requests>\n", Duration ? (double)(IIS->W3Error) / (double)Duration : 0.0, MilDuration ? (((double)(IIS->ErrorCPUTime) / (double)MilDuration) * 100.0) : 0.0, ((IIS->ErrorCPUTime) ? ((double)(IIS->TotalErrorULOnlyCPUTime) / (double)(IIS->ErrorCPUTime)) * 100.0 : 0.0), ((IIS->ErrorCPUTime) ? ((double)(IIS->TotalErrorW3OnlyCPUTime) / (double)(IIS->ErrorCPUTime)) * 100.0 : 0.0), ((IIS->ErrorCPUTime) ? ((double)(IIS->TotalErrorW3FilterCPUTime) / (double)(IIS->ErrorCPUTime)) * 100.0 : 0.0), 0.0, 0.0, 0.0); } fprintf(procFile, "<summary cached='true'>" "<rate>%1.3f</rate>" "<cpu>%1.1f</cpu>" "<component name='UL'>%3d.0</component>" "<component name='W3'>0.0</component>" "<component name='W3Fltr'>0.0</component>" "<component name='ISAPI'>0.0</component>" "<component name='ASP'>0.0</component>" "<component name='CGI'>0.0</component>" "</summary>\n", Duration ? (double)(IIS->CachedResponses) / (double)Duration : 0.0, MilDuration ? (((double)(IIS->CachedCPUTime) / (double)MilDuration) * 100.0) : 0.0, IIS->CachedResponses ? 100 : 0);
fprintf(procFile, "<summary cached='false'>" "<rate percent='%1.1f'>%1.3f</rate>" "<cpu>%1.1f</cpu>" "<component name='UL'>%1.1f</component>" "<component name='W3'>%1.1f</component>" "<component name='W3Fltr'>%1.1f</component>" "<component name='ISAPI'>%1.1f</component>" "<component name='ASP'>%1.1f</component>" "<component name='CGI'>%1.1f</component>" "</summary>\n", ((double)(IIS->TotalRequests - IIS->CachedResponses) / ((double)IIS->TotalRequests)) * 100.0, Duration ? (double)(IIS->TotalRequests - IIS->CachedResponses) / (double)Duration : 0.0, MilDuration ? (((double)(IIS->NonCachedCPUTime) / (double)MilDuration) * 100.0) : 0.0, ((IIS->NonCachedCPUTime) ? ((double)(IIS->TotalFileULOnlyCPUTime + IIS->TotalCGIULOnlyCPUTime + IIS->TotalASPULOnlyCPUTime + IIS->TotalErrorULOnlyCPUTime) / (double)(IIS->NonCachedCPUTime)) * 100.0 : 0.0), ((IIS->NonCachedCPUTime) ? ((double)(IIS->TotalFileW3OnlyCPUTime + IIS->TotalCGIW3OnlyCPUTime + IIS->TotalASPW3OnlyCPUTime + IIS->TotalErrorW3OnlyCPUTime) / (double)(IIS->NonCachedCPUTime)) * 100.0 : 0.0), ((IIS->NonCachedCPUTime) ? ((double)(IIS->TotalW3FilterCPUTime) / (double)(IIS->NonCachedCPUTime)) * 100.0 : 0.0), ((IIS->NonCachedCPUTime) ? ((double)(IIS->TotalASPISAPIOnlyCPUTime) / (double)(IIS->NonCachedCPUTime)) * 100.0 : 0.0), ((IIS->NonCachedCPUTime) ? ((double)(IIS->TotalASPOnlyCPUTime) / (double)(IIS->NonCachedCPUTime)) * 100.0: 0.0), ((IIS->NonCachedCPUTime) ? ((double)(IIS->TotalCGIOnlyCPUTime) / (double)(IIS->NonCachedCPUTime)) * 100.0: 0.0));
fprintf(procFile, "<summary type='totals'>" "<rate>%1.3f</rate>" "<cpu>%1.1f</cpu>" "<component name='UL'>%1.1f</component>" "<component name='W3'>%1.1f</component>" "<component name='W3Fltr'>%1.1f</component>" "<component name='ISAPI'>%1.1f</component>" "<component name='ASP'>%1.1f</component>" "<component name='CGI'>%1.1f</component>" "</summary>\n", Duration ? (double)IIS->TotalRequests / (double)Duration : 0.0, MilDuration ? (((double)(IIS->TotalCPUTime) / (double)MilDuration) * 100.0) : 0.0, ((IIS->TotalCPUTime) ? ((double)(IIS->CachedCPUTime + IIS->TotalFileULOnlyCPUTime + IIS->TotalCGIULOnlyCPUTime + IIS->TotalASPULOnlyCPUTime + IIS->TotalErrorULOnlyCPUTime) / (double)(IIS->TotalCPUTime)) * 100.0 : 0.0), ((IIS->TotalCPUTime) ? ((double)(IIS->TotalFileW3OnlyCPUTime + IIS->TotalCGIW3OnlyCPUTime + IIS->TotalASPW3OnlyCPUTime + IIS->TotalErrorW3OnlyCPUTime) / (double)(IIS->TotalCPUTime)) * 100.0 : 0.0), ((IIS->TotalCPUTime) ? ((double)(IIS->TotalW3FilterCPUTime) / (double)(IIS->TotalCPUTime)) * 100.0 : 0.0), ((IIS->TotalCPUTime) ? ((double)(IIS->TotalASPISAPIOnlyCPUTime) / (double)(IIS->TotalCPUTime)) * 100.0 : 0.0), ((IIS->TotalCPUTime) ? ((double)(IIS->TotalASPOnlyCPUTime) / (double)(IIS->TotalCPUTime)) * 100.0: 0.0), ((IIS->TotalCPUTime) ? ((double)(IIS->TotalCGIOnlyCPUTime) / (double)(IIS->TotalCPUTime)) * 100.0: 0.0)); fprintf(procFile, "</table>\n");
}
RtlZeroMemory(TopHitURLs, sizeof(URL_RECORD) * DISPLAY_SIZE); RtlZeroMemory(TopHitStaticURLs, sizeof(URL_RECORD) * DISPLAY_SIZE); RtlZeroMemory(TopSlowURLs, sizeof(URL_RECORD) * DISPLAY_SIZE); RtlZeroMemory(TopConsumingURLs, sizeof(URL_RECORD) * DISPLAY_SIZE); RtlZeroMemory(TopBytesURLs, sizeof(URL_RECORD) * DISPLAY_SIZE); for (k = 0; k < URL_HASH_TABLESIZE; k++) { pUrl = GetHeadUrlRecord(k); while (pUrl != NULL) { ULONGLONG AverageURLResponseTime = 0; ULONG Found; URL_RECORD tmpUrl1, tmpUrl2; if (pUrl->Requests != 0) { RtlZeroMemory(&tmpUrl1, sizeof(URL_RECORD)); RtlZeroMemory(&tmpUrl2, sizeof(URL_RECORD)); Found = FALSE; for (i = 0; i < DISPLAY_SIZE; i++) { if (Found && tmpUrl1.Requests != 0) { RtlCopyMemory(&tmpUrl2, &TopHitURLs[i], sizeof(URL_RECORD)); RtlCopyMemory(&TopHitURLs[i], &tmpUrl1, sizeof(URL_RECORD)); RtlCopyMemory(&tmpUrl1, &tmpUrl2, sizeof(URL_RECORD)); } else if (!Found) { if (TopHitURLs[i].Requests == 0) { RtlCopyMemory(&TopHitURLs[i], pUrl, sizeof(URL_RECORD)); TopHitURLs[i].URL = CopyUrlStr(pUrl->URL); if (TopHitURLs[i].URL != NULL) { Found = TRUE; } else { RtlZeroMemory(&TopHitURLs[i], sizeof(URL_RECORD)); } } else if (pUrl->Requests > TopHitURLs[i].Requests) { RtlCopyMemory(&tmpUrl1, &TopHitURLs[i], sizeof(URL_RECORD)); RtlCopyMemory(&TopHitURLs[i], pUrl, sizeof(URL_RECORD)); TopHitURLs[i].URL = CopyUrlStr(pUrl->URL); if (TopHitURLs[i].URL != NULL) { Found = TRUE; } else { RtlCopyMemory(&TopHitURLs[i], &tmpUrl1, sizeof(URL_RECORD)); RtlZeroMemory(&tmpUrl1, sizeof(URL_RECORD)); } } } } if (tmpUrl1.Requests != 0) { free(tmpUrl1.URL); } RtlZeroMemory(&tmpUrl1, sizeof(URL_RECORD)); RtlZeroMemory(&tmpUrl2, sizeof(URL_RECORD)); Found = FALSE; for (i = 0; i < DISPLAY_SIZE; i++) { if (Found && tmpUrl1.Requests != 0) { RtlCopyMemory(&tmpUrl2, &TopHitStaticURLs[i], sizeof(URL_RECORD)); RtlCopyMemory(&TopHitStaticURLs[i], &tmpUrl1, sizeof(URL_RECORD)); RtlCopyMemory(&tmpUrl1, &tmpUrl2, sizeof(URL_RECORD)); } else if (!Found) { if ((pUrl->UrlType == EVENT_TRACE_TYPE_W3CORE_FILEREQ || pUrl->Hits > 0) && TopHitStaticURLs[i].Requests == 0) {
RtlCopyMemory(&TopHitStaticURLs[i], pUrl, sizeof(URL_RECORD)); TopHitStaticURLs[i].URL = CopyUrlStr(pUrl->URL); if (TopHitStaticURLs[i].URL != NULL) { Found = TRUE; } else { RtlZeroMemory(&TopHitStaticURLs[i], sizeof(URL_RECORD)); } } else if ((pUrl->UrlType == EVENT_TRACE_TYPE_W3CORE_FILEREQ || pUrl->Hits > 0) && pUrl->Requests > TopHitStaticURLs[i].Requests) {
RtlCopyMemory(&tmpUrl1, &TopHitStaticURLs[i], sizeof(URL_RECORD)); RtlCopyMemory(&TopHitStaticURLs[i], pUrl, sizeof(URL_RECORD)); TopHitStaticURLs[i].URL = CopyUrlStr(pUrl->URL); if (TopHitStaticURLs[i].URL != NULL) { Found = TRUE; } else { RtlCopyMemory(&TopHitStaticURLs[i], &tmpUrl1, sizeof(URL_RECORD)); RtlZeroMemory(&tmpUrl1, sizeof(URL_RECORD)); } } } } if (tmpUrl1.Requests != 0) { free(tmpUrl1.URL); } AverageURLResponseTime = pUrl->TotalResponseTime / pUrl->Requests; RtlZeroMemory(&tmpUrl1, sizeof(URL_RECORD)); RtlZeroMemory(&tmpUrl2, sizeof(URL_RECORD)); Found = FALSE; for (i = 0; i < DISPLAY_SIZE; i++) { if (Found && tmpUrl1.Requests != 0) { RtlCopyMemory(&tmpUrl2, &TopSlowURLs[i], sizeof(URL_RECORD)); RtlCopyMemory(&TopSlowURLs[i], &tmpUrl1, sizeof(URL_RECORD)); RtlCopyMemory(&tmpUrl1, &tmpUrl2, sizeof(URL_RECORD)); } else if (!Found) { if (TopSlowURLs[i].Requests == 0) { RtlCopyMemory(&TopSlowURLs[i], pUrl, sizeof(URL_RECORD)); TopSlowURLs[i].URL = CopyUrlStr(pUrl->URL); if (TopSlowURLs[i].URL != NULL) { Found = TRUE; } else { RtlZeroMemory(&TopSlowURLs[i], sizeof(URL_RECORD)); } } else if (AverageURLResponseTime > (TopSlowURLs[i].TotalResponseTime / TopSlowURLs[i].Requests)) { RtlCopyMemory(&tmpUrl1, &TopSlowURLs[i], sizeof(URL_RECORD)); RtlCopyMemory(&TopSlowURLs[i], pUrl, sizeof(URL_RECORD)); TopSlowURLs[i].URL = CopyUrlStr(pUrl->URL); if (TopSlowURLs[i].URL != NULL) { Found = TRUE; } else { RtlCopyMemory(&TopSlowURLs[i], &tmpUrl1, sizeof(URL_RECORD)); RtlZeroMemory(&tmpUrl1, sizeof(URL_RECORD)); } } } } if (tmpUrl1.Requests != 0) { free(tmpUrl1.URL); } RtlZeroMemory(&tmpUrl1, sizeof(URL_RECORD)); RtlZeroMemory(&tmpUrl2, sizeof(URL_RECORD)); Found = FALSE; for (i = 0; i < DISPLAY_SIZE; i++) { if (Found && tmpUrl1.Requests != 0) { RtlCopyMemory(&tmpUrl2, &TopConsumingURLs[i], sizeof(URL_RECORD)); RtlCopyMemory(&TopConsumingURLs[i], &tmpUrl1, sizeof(URL_RECORD)); RtlCopyMemory(&tmpUrl1, &tmpUrl2, sizeof(URL_RECORD)); } else if (!Found) { if (TopConsumingURLs[i].Requests == 0) { RtlCopyMemory(&TopConsumingURLs[i], pUrl, sizeof(URL_RECORD)); TopConsumingURLs[i].URL = CopyUrlStr(pUrl->URL); if (TopConsumingURLs[i].URL != NULL) { Found = TRUE; } else { RtlZeroMemory(&TopConsumingURLs[i], sizeof(URL_RECORD)); } } else if ((pUrl->KCPUTime + pUrl->UCPUTime) > (TopConsumingURLs[i].KCPUTime + TopConsumingURLs[i].UCPUTime)) { RtlCopyMemory(&tmpUrl1, &TopConsumingURLs[i], sizeof(URL_RECORD)); RtlCopyMemory(&TopConsumingURLs[i], pUrl, sizeof(URL_RECORD)); TopConsumingURLs[i].URL = CopyUrlStr(pUrl->URL); if (TopConsumingURLs[i].URL != NULL) { Found = TRUE; } else { RtlCopyMemory(&TopConsumingURLs[i], &tmpUrl1, sizeof(URL_RECORD)); RtlZeroMemory(&tmpUrl1, sizeof(URL_RECORD)); } } } } if (tmpUrl1.Requests != 0) { free(tmpUrl1.URL); } RtlZeroMemory(&tmpUrl1, sizeof(URL_RECORD)); RtlZeroMemory(&tmpUrl2, sizeof(URL_RECORD)); Found = FALSE; for (i = 0; i < DISPLAY_SIZE; i++) { if (Found && tmpUrl1.Requests != 0) { RtlCopyMemory(&tmpUrl2, &TopBytesURLs[i], sizeof(URL_RECORD)); RtlCopyMemory(&TopBytesURLs[i], &tmpUrl1, sizeof(URL_RECORD)); RtlCopyMemory(&tmpUrl1, &tmpUrl2, sizeof(URL_RECORD)); } else if (!Found) { if (TopBytesURLs[i].Requests == 0) { RtlCopyMemory(&TopBytesURLs[i], pUrl, sizeof(URL_RECORD)); TopBytesURLs[i].URL = CopyUrlStr(pUrl->URL); if (TopBytesURLs[i].URL != NULL) { Found = TRUE; } else { RtlZeroMemory(&TopBytesURLs[i], sizeof(URL_RECORD)); } } else if (pUrl->BytesSent > TopBytesURLs[i].BytesSent) { RtlCopyMemory(&tmpUrl1, &TopBytesURLs[i], sizeof(URL_RECORD)); RtlCopyMemory(&TopBytesURLs[i], pUrl, sizeof(URL_RECORD)); TopBytesURLs[i].URL = CopyUrlStr(pUrl->URL); if (TopBytesURLs[i].URL != NULL) { Found = TRUE; } else { RtlCopyMemory(&TopBytesURLs[i], &tmpUrl1, sizeof(URL_RECORD)); RtlZeroMemory(&tmpUrl1, sizeof(URL_RECORD)); } } } } if (tmpUrl1.Requests != 0) { free(tmpUrl1.URL); } } if (pUrl->URL) { free(pUrl->URL); } free(pUrl); pUrl = GetHeadUrlRecord(k); } }
fprintf( procFile, "<table title='Most Requested URLs' top='%d'>", DISPLAY_SIZE);
for (i = 0; i < DISPLAY_SIZE && TopHitURLs[i].Requests != 0; i++) { ULONGLONG AverageURLResponseTime = 0; CHAR ReducedUrl[URL_NAME_COLUMN_SIZE + 1]; char* strPrint;
if (TopHitURLs[i].Requests != 0) { AverageURLResponseTime = TopHitURLs[i].TotalResponseTime / TopHitURLs[i].Requests; } RemoveCtrlCharA(TopHitURLs[i].URL, strlen(TopHitURLs[i].URL)); if (strlen(TopHitURLs[i].URL) > URL_NAME_COLUMN_SIZE) { ReduceStringA(ReducedUrl, URL_NAME_COLUMN_SIZE + 1, TopHitURLs[i].URL); strPrint = ReducedUrl; }else{ strPrint = TopHitURLs[i].URL; } fprintf(procFile, "<url name='%s'>" "<site_id>%d</site_id>" "<rate>%1.3f</rate>" "<cache_hit>%1.1f</cache_hit>" "<response_time>%1.1f</response_time>" "</url>\n", strPrint, TopHitURLs[i].SiteId, (Duration ? ((double)TopHitURLs[i].Requests / (double)Duration) : 0.0), TopHitURLs[i].Requests ? ((double)TopHitURLs[i].Hits / (double)TopHitURLs[i].Requests * 100.0) : 0.0, ((double)AverageURLResponseTime) / 10000.0);
} fprintf( procFile, "</table>\n" ); fprintf(procFile, "<table title='Most Requested Static URLs' top='%d'>\n", DISPLAY_SIZE);
for (i = 0; i < DISPLAY_SIZE && TopHitStaticURLs[i].Requests != 0; i++) { char* strPrint; ULONGLONG AverageURLResponseTime = 0; CHAR ReducedUrl[URL_NAME_COLUMN_SIZE + 1];
if (TopHitStaticURLs[i].Requests != 0) { AverageURLResponseTime = TopHitStaticURLs[i].TotalResponseTime / TopHitStaticURLs[i].Requests; } RemoveCtrlCharA(TopHitStaticURLs[i].URL, strlen(TopHitStaticURLs[i].URL)); if (strlen(TopHitStaticURLs[i].URL) > URL_NAME_COLUMN_SIZE) { ReduceStringA(ReducedUrl, URL_NAME_COLUMN_SIZE + 1, TopHitStaticURLs[i].URL); strPrint = ReducedUrl; }else{ strPrint = TopHitStaticURLs[i].URL; } fprintf(procFile, "<url name='%s'>" "<site_id>%d</site_id>" "<rate>%1.3f</rate>" "<cache_hit>%1.1f</cache_hit>" "<response_time>%1.1f</response_time>" "</url>\n", strPrint, TopHitStaticURLs[i].SiteId, (Duration ? ((double)TopHitStaticURLs[i].Requests / (double)Duration) : 0.0), TopHitStaticURLs[i].Requests ? ((double)TopHitStaticURLs[i].Hits / (double)TopHitStaticURLs[i].Requests * 100.0) : 0.0, ((double)AverageURLResponseTime) / 10000.0); } fprintf(procFile, "</table>\n"); fprintf(procFile, "<table title='Slowest URLs' top='%d'>\n", DISPLAY_SIZE );
for (i = 0; i < DISPLAY_SIZE && TopSlowURLs[i].Requests != 0; i++) { char* strPrint; ULONGLONG AverageURLResponseTime = 0; CHAR ReducedUrl[URL_NAME_COLUMN_SIZE + 1];
if (TopSlowURLs[i].Requests != 0) { AverageURLResponseTime = TopSlowURLs[i].TotalResponseTime / TopSlowURLs[i].Requests; } RemoveCtrlCharA(TopSlowURLs[i].URL, strlen(TopSlowURLs[i].URL)); if (strlen(TopSlowURLs[i].URL) > URL_NAME_COLUMN_SIZE) { ReduceStringA(ReducedUrl, URL_NAME_COLUMN_SIZE + 1, TopSlowURLs[i].URL); strPrint = ReducedUrl; }else{ strPrint = TopSlowURLs[i].URL; } fprintf(procFile, "<url name='%s'>" "<site_id>%d</site_id>" "<rate>%1.3f</rate>" "<cache_hit>%1.1f</cache_hit>" "<response_time>%1.1f</response_time>" "</url>\n", strPrint, TopSlowURLs[i].SiteId, (Duration ? ((double)TopSlowURLs[i].Requests / (double)Duration) : 0.0), TopSlowURLs[i].Requests ? ((double)TopSlowURLs[i].Hits / (double)TopSlowURLs[i].Requests * 100.0) : 0.0, ((double)AverageURLResponseTime) / 10000.0); } fprintf(procFile, "</table>\n" );
if (PrintCPUUsage) { fprintf(procFile, "<table title='URLs with the Most CPU Usage' top='%d'>\n", DISPLAY_SIZE);
for (i = 0; i < DISPLAY_SIZE && TopConsumingURLs[i].Requests != 0; i++) { char* strPrint; CHAR ReducedUrl[URL_NAME_COLUMN_SIZE + 1]; RemoveCtrlCharA(TopConsumingURLs[i].URL, strlen(TopConsumingURLs[i].URL)); if (strlen(TopConsumingURLs[i].URL) > URL_NAME_COLUMN_SIZE) { ReduceStringA(ReducedUrl, URL_NAME_COLUMN_SIZE + 1, TopConsumingURLs[i].URL); strPrint = ReducedUrl; }else{ strPrint = TopConsumingURLs[i].URL; }
fprintf(procFile, "<url name='%s'>" "<site_id>%d</site_id>" "<rate>%1.3f</rate>" "<cpu>%1.2f</cpu>" "</url>\n", strPrint, TopConsumingURLs[i].SiteId, (Duration ? ((double)TopConsumingURLs[i].Requests / (double)Duration) : 0.0), MilDuration ? ((((double)TopConsumingURLs[i].KCPUTime + (double)TopConsumingURLs[i].UCPUTime) / (double)MilDuration) * 100.0) : 0.0); }
fprintf(procFile, "</table>\n" ); }
fprintf(procFile, "<table title='URLs with the Most Bytes Sent' top='%d'>\n", DISPLAY_SIZE);
for (i = 0; i < DISPLAY_SIZE && TopBytesURLs[i].Requests != 0; i++) { char* strPrint; CHAR ReducedUrl[URL_NAME_COLUMN_SIZE + 1];
RemoveCtrlCharA(TopBytesURLs[i].URL, strlen(TopBytesURLs[i].URL)); if (strlen(TopBytesURLs[i].URL) > URL_NAME_COLUMN_SIZE) { ReduceStringA(ReducedUrl, URL_NAME_COLUMN_SIZE + 1, TopBytesURLs[i].URL); strPrint = ReducedUrl; }else{ strPrint = TopBytesURLs[i].URL; } fprintf(procFile, "<url name='%s'>" "<site_id>%d</site_id>" "<rate>%1.3f</rate>" "<cache_hit>%1.1f</cache_hit>" "<bytes_sent_per_sec>%d</bytes_sent_per_sec>" "</url>\n", strPrint, TopBytesURLs[i].SiteId, (Duration ? ((double)TopBytesURLs[i].Requests / (double)Duration) : 0.0), TopBytesURLs[i].Requests ? ((double)TopBytesURLs[i].Hits / (double)TopBytesURLs[i].Requests * 100.0) : 0.0, Duration ? TopBytesURLs[i].BytesSent/ Duration : 0); } fprintf(procFile, "</table>\n" );
for (i = 0; i < DISPLAY_SIZE; i++) { if (TopHitURLs[i].Requests != 0 && TopHitURLs[i].URL != NULL) { free(TopHitURLs[i].URL); } if (TopHitStaticURLs[i].Requests != 0 && TopHitStaticURLs[i].URL != NULL) { free(TopHitStaticURLs[i].URL); } if (TopSlowURLs[i].Requests != 0 && TopSlowURLs[i].URL != NULL) { free(TopSlowURLs[i].URL); } if (TopConsumingURLs[i].Requests != 0 && TopConsumingURLs[i].URL != NULL) { free(TopConsumingURLs[i].URL); } if (TopBytesURLs[i].Requests != 0 && TopBytesURLs[i].URL != NULL) { free(TopBytesURLs[i].URL); } }
RtlZeroMemory(TopHitClients, sizeof(CLIENT_RECORD) * DISPLAY_SIZE); RtlZeroMemory(TopSlowClients, sizeof(CLIENT_RECORD) * DISPLAY_SIZE); pClient = GetHeadClientRecord(); while (pClient != NULL) { ULONGLONG AverageClientResponseTime = 0; ULONG Found; CLIENT_RECORD tmpClient1, tmpClient2; if (pClient->Requests != 0) { RtlZeroMemory(&tmpClient1, sizeof(CLIENT_RECORD)); RtlZeroMemory(&tmpClient2, sizeof(CLIENT_RECORD)); Found = FALSE; for (i = 0; i < DISPLAY_SIZE; i++) { if (Found && tmpClient1.Requests != 0) { RtlCopyMemory(&tmpClient2, &TopHitClients[i], sizeof(CLIENT_RECORD)); RtlCopyMemory(&TopHitClients[i], &tmpClient1, sizeof(CLIENT_RECORD)); RtlCopyMemory(&tmpClient1, &tmpClient2, sizeof(CLIENT_RECORD)); } else if (!Found) { if (TopHitClients[i].Requests == 0) { RtlCopyMemory(&TopHitClients[i], pClient, sizeof(CLIENT_RECORD)); Found = TRUE; } else if (pClient->Requests > TopHitClients[i].Requests) { RtlCopyMemory(&tmpClient1, &TopHitClients[i], sizeof(CLIENT_RECORD)); RtlCopyMemory(&TopHitClients[i], pClient, sizeof(CLIENT_RECORD)); Found = TRUE; } } } AverageClientResponseTime = pClient->TotalResponseTime / pClient->Requests; RtlZeroMemory(&tmpClient1, sizeof(CLIENT_RECORD)); RtlZeroMemory(&tmpClient2, sizeof(CLIENT_RECORD)); Found = FALSE; for (i = 0; i < DISPLAY_SIZE; i++) { if (Found && tmpClient1.Requests != 0) { RtlCopyMemory(&tmpClient2, &TopSlowClients[i], sizeof(CLIENT_RECORD)); RtlCopyMemory(&TopSlowClients[i], &tmpClient1, sizeof(CLIENT_RECORD)); RtlCopyMemory(&tmpClient1, &tmpClient2, sizeof(CLIENT_RECORD)); } else if (!Found) { if (TopSlowClients[i].Requests == 0) { RtlCopyMemory(&TopSlowClients[i], pClient, sizeof(CLIENT_RECORD)); Found = TRUE; } else if (AverageClientResponseTime > (TopSlowClients[i].TotalResponseTime / TopSlowClients[i].Requests)) { RtlCopyMemory(&tmpClient1, &TopSlowClients[i], sizeof(CLIENT_RECORD)); RtlCopyMemory(&TopSlowClients[i], pClient, sizeof(CLIENT_RECORD)); Found = TRUE; } } } } free(pClient); pClient = GetHeadClientRecord(); }
fprintf(procFile, "<table title='Clients with the Most Requests' top='%d'>\n", DISPLAY_SIZE);
for (i = 0; i < DISPLAY_SIZE && TopHitClients[i].Requests != 0; i++) { ULONGLONG AverageClientResponseTime = 0; CHAR ipAddrBuffer[MAX_ADDRESS_LENGTH]; PCHAR pszA = &ipAddrBuffer[0];
if (TopHitClients[i].Requests != 0) { AverageClientResponseTime = TopHitClients[i].TotalResponseTime / TopHitClients[i].Requests; }
DecodeIpAddressA(TopHitClients[i].IpAddrType, &TopHitClients[i].IpAddrV4, &TopHitClients[i].IpAddrV6[0], pszA);
fprintf(procFile, "<client ip='%s'>" "<rate>%1.3f</rate>" "<cache_hit>%1.1f</cache_hit>" "<response_time>%I64u</response_time>" "</client>\n", ipAddrBuffer, (Duration ? ((double)TopHitClients[i].Requests / (double)Duration) : 0.0), TopHitClients[i].Requests ? ((double)TopHitClients[i].Hits / (double)TopHitClients[i].Requests * 100.0) : 0.0, AverageClientResponseTime / 10000); } fprintf(procFile, "</table>\n" ); fprintf(procFile, "<table title='Clients with the Slowest Responses' top='%d'>", DISPLAY_SIZE);
for (i = 0; i < DISPLAY_SIZE && TopSlowClients[i].Requests != 0; i++) { ULONGLONG AverageClientResponseTime = 0; CHAR ipAddrBuffer[MAX_ADDRESS_LENGTH]; PCHAR pszA = &ipAddrBuffer[0];
if (TopSlowClients[i].Requests != 0) { AverageClientResponseTime = TopSlowClients[i].TotalResponseTime / TopSlowClients[i].Requests; }
DecodeIpAddressA(TopHitClients[i].IpAddrType, &TopHitClients[i].IpAddrV4, &TopHitClients[i].IpAddrV6[0], pszA);
fprintf(procFile, "<client ip='%s'>" "<rate>%1.3f</rate>" "<cache_hit>%1.1f</cache_hit>" "<response_time>%I64u</response_time>" "</client>\n", ipAddrBuffer, (Duration ? ((double)TopSlowClients[i].Requests / (double)Duration) : 0.0), TopSlowClients[i].Requests ? ((double)TopSlowClients[i].Hits / (double)TopSlowClients[i].Requests * 100.0) : 0.0, AverageClientResponseTime / 10000); } fprintf(procFile, "</table>" );
RtlZeroMemory(TopHitSites, sizeof(SITE_RECORD) * DISPLAY_SIZE); RtlZeroMemory(TopSlowSites, sizeof(SITE_RECORD) * DISPLAY_SIZE); RtlZeroMemory(TopConsumingSites, sizeof(SITE_RECORD) * DISPLAY_SIZE); RtlZeroMemory(TopBytesSites, sizeof(SITE_RECORD) * DISPLAY_SIZE); pSite = GetHeadSiteRecord(); while (pSite != NULL) { ULONGLONG AverageSiteResponseTime = 0; ULONG Found; SITE_RECORD tmpSite1, tmpSite2; if (pSite->Requests != 0) { RtlZeroMemory(&tmpSite1, sizeof(SITE_RECORD)); RtlZeroMemory(&tmpSite2, sizeof(SITE_RECORD)); Found = FALSE; for (i = 0; i < DISPLAY_SIZE; i++) { if (Found && tmpSite1.Requests != 0) { RtlCopyMemory(&tmpSite2, &TopHitSites[i], sizeof(SITE_RECORD)); RtlCopyMemory(&TopHitSites[i], &tmpSite1, sizeof(SITE_RECORD)); RtlCopyMemory(&tmpSite1, &tmpSite2, sizeof(SITE_RECORD)); } else if (!Found) { if (TopHitSites[i].Requests == 0) { RtlCopyMemory(&TopHitSites[i], pSite, sizeof(SITE_RECORD)); Found = TRUE; } else if (pSite->Requests > TopHitSites[i].Requests) { RtlCopyMemory(&tmpSite1, &TopHitSites[i], sizeof(SITE_RECORD)); RtlCopyMemory(&TopHitSites[i], pSite, sizeof(SITE_RECORD)); Found = TRUE; } } } AverageSiteResponseTime = pSite->TotalResponseTime / pSite->Requests; RtlZeroMemory(&tmpSite1, sizeof(SITE_RECORD)); RtlZeroMemory(&tmpSite2, sizeof(SITE_RECORD)); Found = FALSE; for (i = 0; i < DISPLAY_SIZE; i++) { if (Found && tmpSite1.Requests != 0) { RtlCopyMemory(&tmpSite2, &TopSlowSites[i], sizeof(SITE_RECORD)); RtlCopyMemory(&TopSlowSites[i], &tmpSite1, sizeof(SITE_RECORD)); RtlCopyMemory(&tmpSite1, &tmpSite2, sizeof(SITE_RECORD)); } else if (!Found) { if (TopSlowSites[i].Requests == 0) { RtlCopyMemory(&TopSlowSites[i], pSite, sizeof(SITE_RECORD)); Found = TRUE; } else if (AverageSiteResponseTime > (TopSlowSites[i].TotalResponseTime / TopSlowSites[i].Requests)) { RtlCopyMemory(&tmpSite1, &TopSlowSites[i], sizeof(SITE_RECORD)); RtlCopyMemory(&TopSlowSites[i], pSite, sizeof(SITE_RECORD)); Found = TRUE; } } } RtlZeroMemory(&tmpSite1, sizeof(SITE_RECORD)); RtlZeroMemory(&tmpSite2, sizeof(SITE_RECORD)); Found = FALSE; for (i = 0; i < DISPLAY_SIZE; i++) { if (Found && tmpSite1.Requests != 0) { RtlCopyMemory(&tmpSite2, &TopConsumingSites[i], sizeof(SITE_RECORD)); RtlCopyMemory(&TopConsumingSites[i], &tmpSite1, sizeof(SITE_RECORD)); RtlCopyMemory(&tmpSite1, &tmpSite2, sizeof(SITE_RECORD)); } else if (!Found) { if (TopConsumingSites[i].Requests == 0) { RtlCopyMemory(&TopConsumingSites[i], pSite, sizeof(SITE_RECORD)); Found = TRUE; } else if ((pSite->KCPUTime + pSite->UCPUTime) > (TopConsumingSites[i].KCPUTime + TopConsumingSites[i].UCPUTime)) { RtlCopyMemory(&tmpSite1, &TopConsumingSites[i], sizeof(SITE_RECORD)); RtlCopyMemory(&TopConsumingSites[i], pSite, sizeof(SITE_RECORD)); Found = TRUE; } } } RtlZeroMemory(&tmpSite1, sizeof(SITE_RECORD)); RtlZeroMemory(&tmpSite2, sizeof(SITE_RECORD)); Found = FALSE; for (i = 0; i < DISPLAY_SIZE; i++) { if (Found && tmpSite1.Requests != 0) { RtlCopyMemory(&tmpSite2, &TopBytesSites[i], sizeof(SITE_RECORD)); RtlCopyMemory(&TopBytesSites[i], &tmpSite1, sizeof(SITE_RECORD)); RtlCopyMemory(&tmpSite1, &tmpSite2, sizeof(SITE_RECORD)); } else if (!Found) { if (TopBytesSites[i].Requests == 0) { RtlCopyMemory(&TopBytesSites[i], pSite, sizeof(SITE_RECORD)); Found = TRUE; } else if (pSite->BytesSent > TopBytesSites[i].BytesSent) { RtlCopyMemory(&tmpSite1, &TopBytesSites[i], sizeof(SITE_RECORD)); RtlCopyMemory(&TopBytesSites[i], pSite, sizeof(SITE_RECORD)); Found = TRUE; } } } } free(pSite); pSite = GetHeadSiteRecord(); } fprintf(procFile, "<table title='Sites with the Most Requests' top='%d'>\n", DISPLAY_SIZE);
for (i = 0; i < DISPLAY_SIZE && TopHitSites[i].Requests != 0; i++) { ULONGLONG AverageSiteResponseTime = 0;
if (TopHitSites[i].Requests != 0) { AverageSiteResponseTime = TopHitSites[i].TotalResponseTime / TopHitSites[i].Requests; } fprintf(procFile, "<site id='%d'>" "<rate>%1.3f</rate>" "<response_time>%I64u</response_time>" "<cache_hits>%1.1f</cache_hits>" "<static>%1.1f</static>" "<cgi>%1.1f</cgi>" "<asp>%1.1f</asp>" "</site>\n", TopHitSites[i].SiteId, (Duration ? ((double)TopHitSites[i].Requests / (double)Duration) : 0.0), AverageSiteResponseTime / 10000, TopHitSites[i].Requests ? ((double)TopHitSites[i].Hits / (double)TopHitSites[i].Requests * 100.0) : 0.0, TopHitSites[i].Requests ? ((double)TopHitSites[i].FileRequests / (double)TopHitSites[i].Requests * 100.0) : 0.0, TopHitSites[i].Requests ? ((double)TopHitSites[i].CGIRequests / (double)TopHitSites[i].Requests * 100.0) : 0.0, TopHitSites[i].Requests ? ((double)TopHitSites[i].ISAPIRequests / (double)TopHitSites[i].Requests * 100.0) : 0.0); } fprintf(procFile, "</table>\n" ); fprintf(procFile, "<table title='Sites with the Slowest Responses' top='%d'>\n", DISPLAY_SIZE);
for (i = 0; i < DISPLAY_SIZE && TopSlowSites[i].Requests != 0; i++) { ULONGLONG AverageSiteResponseTime = 0;
if (TopSlowSites[i].Requests != 0) { AverageSiteResponseTime = TopSlowSites[i].TotalResponseTime / TopSlowSites[i].Requests; } fprintf(procFile, "<site id='%d'>" "<rate>%1.3f</rate>" "<response_time>%I64u</response_time>" "<cache_hits>%1.1f</cache_hits>" "<static>%1.1f</static>" "<cgi>%1.1f</cgi>" "<asp>%1.1f</asp>" "</site>\n", TopSlowSites[i].SiteId, (Duration ? ((double)TopSlowSites[i].Requests / (double)Duration) : 0.0), AverageSiteResponseTime / 10000, TopSlowSites[i].Requests ? ((double)TopSlowSites[i].Hits / (double)TopSlowSites[i].Requests * 100.0) : 0.0, TopSlowSites[i].Requests ? ((double)TopSlowSites[i].FileRequests / (double)TopSlowSites[i].Requests * 100.0) : 0.0, TopSlowSites[i].Requests ? ((double)TopSlowSites[i].CGIRequests / (double)TopSlowSites[i].Requests * 100.0) : 0.0, TopSlowSites[i].Requests ? ((double)TopSlowSites[i].ISAPIRequests / (double)TopSlowSites[i].Requests * 100.0) : 0.0); } fprintf(procFile, "</table>\n" );
if (PrintCPUUsage) { fprintf(procFile, "<table title='Sites with the Most CPU Time Usage' top='%d'>\n", DISPLAY_SIZE );
for (i = 0; i < DISPLAY_SIZE && TopConsumingSites[i].Requests != 0; i++) { ULONGLONG AverageSiteResponseTime = 0;
if (TopConsumingSites[i].Requests != 0) { AverageSiteResponseTime = TopConsumingSites[i].TotalResponseTime / TopConsumingSites[i].Requests; } fprintf(procFile, "<site id='%d'>" "<rate>%1.3f</rate>" "<cache_hits>%1.1f</cache_hits>" "<response_time>%I64u</response_time>" "<cpu_time units='ms'>%d</cpu_time>" "<cpu>%1.1f</cpu>" "</site>\n", TopConsumingSites[i].SiteId, (Duration ? ((double)TopConsumingSites[i].Requests / (double)Duration) : 0.0), TopConsumingSites[i].Requests ? ((double)TopConsumingSites[i].Hits / (double)TopConsumingSites[i].Requests * 100.0) : 0.0, AverageSiteResponseTime / 10000, TopConsumingSites[i].Requests ? (TopConsumingSites[i].KCPUTime + TopConsumingSites[i].UCPUTime) / TopConsumingSites[i].Requests : 0, MilDuration ? ((((double)TopConsumingSites[i].KCPUTime + (double)TopConsumingSites[i].UCPUTime) / (double)MilDuration) * 100.0) : 0.0); } fprintf(procFile, "</table>\n" ); }
fprintf(procFile, "<table title='Sites with the Most Bytes Sent' top='%d'>\n", DISPLAY_SIZE ); for (i = 0; i < DISPLAY_SIZE && TopBytesSites[i].Requests != 0; i++) { fprintf(procFile, "<site id='%d'>" "<rate>%1.3f</rate>" "<bytes>%d</bytes>" "<cache_hits>%1.1f</cache_hits>" "<static>%1.1f</static>" "<cgi>%1.1f</cgi>" "<asp>%1.1f</asp>" "</site>\n", TopBytesSites[i].SiteId, (Duration ? ((double)TopBytesSites[i].Requests / (double)Duration) : 0.0), Duration ? TopBytesSites[i].BytesSent / Duration : 0, TopBytesSites[i].Requests ? ((double)TopBytesSites[i].Hits / (double)TopBytesSites[i].Requests * 100.0) : 0.0, TopBytesSites[i].Requests ? ((double)TopBytesSites[i].FileRequests / (double)TopBytesSites[i].Requests * 100.0) : 0.0, TopBytesSites[i].Requests ? ((double)TopBytesSites[i].CGIRequests / (double)TopBytesSites[i].Requests * 100.0) : 0.0, TopBytesSites[i].Requests ? ((double)TopBytesSites[i].ISAPIRequests / (double)TopBytesSites[i].Requests * 100.0) : 0.0); }
fprintf(procFile, "</table>\n" );
free(IIS); }
void WriteSummary() { FILE* SummaryFile; PLIST_ENTRY Head, Next; PMOF_INFO pMofInfo; ULONG i;
WCHAR buffer[MAXSTR]; FILETIME StTm, StlTm; LARGE_INTEGER LargeTmp; SYSTEMTIME tmf, emf; BOOL bResult;
if( NULL == TraceContext->SummaryFileName ){ return; }
if( 0 == TotalEventCount ){ return; }
SummaryFile = _wfopen( TraceContext->SummaryFileName, L"w" ); if (SummaryFile == NULL){ return; }
fwprintf(SummaryFile,L"Files Processed:\n");
for (i=0; i<TraceContext->LogFileCount; i++) { fwprintf(SummaryFile,L"\t%s\n",TraceContext->LogFileName[i]); }
LargeTmp.QuadPart = CurrentSystem.StartTime; StTm.dwHighDateTime = LargeTmp.HighPart; StTm.dwLowDateTime = LargeTmp.LowPart; FileTimeToLocalFileTime(&StTm, &StlTm);
bResult = FileTimeToSystemTime ( &StlTm, &tmf );
if( ! bResult || tmf.wMonth > 12 ){ ZeroMemory( &tmf, sizeof(SYSTEMTIME) ); buffer[0] = '\0'; }else{ GetDateFormatW( LOCALE_USER_DEFAULT, DATE_LONGDATE, &tmf, NULL, buffer, MAXSTR ); }
fwprintf(SummaryFile, L"Total Buffers Processed %d\n" L"Total Events Processed %d\n" L"Total Events Lost %d\n" L"Start Time %ws\n", TotalBuffersRead, TotalEventCount, TotalEventsLost, buffer );
LargeTmp.QuadPart = CurrentSystem.EndTime; StTm.dwHighDateTime = LargeTmp.HighPart; StTm.dwLowDateTime = LargeTmp.LowPart; FileTimeToLocalFileTime(&StTm, &StlTm);
bResult = FileTimeToSystemTime ( &StlTm, &emf );
if( ! bResult || tmf.wMonth > 12 ){ ZeroMemory( &tmf, sizeof(SYSTEMTIME) ); buffer[0] = '\0'; }else{ GetDateFormatW( LOCALE_USER_DEFAULT, DATE_LONGDATE, &emf, NULL, buffer, MAXSTR ); }
ElapseTime = CurrentSystem.EndTime - CurrentSystem.StartTime; fwprintf(SummaryFile, L"End Time %ws\n" L"Elapsed Time %I64d sec\n", buffer, (ElapseTime / 10000000) );
fwprintf(SummaryFile, L"+-------------------------------------------------------------------------------------+\n" L"|%10s %-20s %-10s %-38s|\n" L"+-------------------------------------------------------------------------------------+\n", L"Event Count", L"Event Name", L"Event Type", L"Guid" );
Head = &CurrentSystem.EventListHead; Next = Head->Flink; while (Head != Next) { WCHAR wstr[MAXSTR]; PWCHAR str; WCHAR s[MAX_GUID_STRING_SIZE]; PLIST_ENTRY vHead, vNext; PMOF_VERSION pMofVersion;
RtlZeroMemory(&wstr[0], MAXSTR*sizeof(WCHAR));
pMofInfo = CONTAINING_RECORD(Next, MOF_INFO, Entry); Next = Next->Flink;
if (pMofInfo->EventCount > 0) { str = CpdiGuidToString(&s[0], MAX_GUID_STRING_SIZE, (LPGUID)&pMofInfo->Guid);
if( pMofInfo->strDescription != NULL ){ StringCchCopyW( wstr, MAXSTR, pMofInfo->strDescription ); }
//
// Get event count by type from MOF_VERSION structure
//
vHead = &pMofInfo->VersionHeader; vNext = vHead->Flink;
while (vHead != vNext) {
pMofVersion = CONTAINING_RECORD(vNext, MOF_VERSION, Entry); vNext = vNext->Flink;
if (pMofVersion->EventCountByType != 0) {
fwprintf(SummaryFile,L"| %10d %-20s %-10s %38s|\n", pMofVersion->EventCountByType, wstr, pMofVersion->strType ? pMofVersion->strType : GUID_TYPE_DEFAULT, str); } } } }
fwprintf(SummaryFile, L"+-------------------------------------------------------------------------------------+\n" ); fclose( SummaryFile ); }
|