perfmon
tool. The basic structure is very similar to the Basic Echo Server example and you should go and read about that first and have a good understanding of how everything fits together. This document will only cover the differences between the Basic Echo Server example and this example. perfmon
tool. The example includes such a DLL and the server project will build the DLL when the server is built.
if (commandLine.RegisterCounters()) { if (CPerformanceCounters::InstallCounters()) { OutputEx(_T("Counters installed")); } else { OutputEx(_T("Counters already installed")); } } else if (commandLine.UnRegisterCounters()) { if (CPerformanceCounters::RemoveCounters()) { OutputEx(_T("Counters Removed")); } else { OutputEx(_T("Counters not installed")); } }
perfmon
application; you'll probably want to change the default security descriptor that we use here. true
to the constructor. This determines if we attempt to enable performance counters at all and, in a real server, could be externally configured to allow for running the server either with or without performance monitoring enabled. Why might you want to run without monitoring? Well, to create the shared memory that the library requires for communication you need to have the SE_CREATE_GLOBAL_NAME
privilege on your account, not having this privilege will prevent you from running the server if you attempt to enable performance counters, so by allowing the server to be configured to run without counters you may make the server easier to develop and debug in some circumstances. CSecurityDescriptorAllowAll sd;
CSecurityAttributes sa(sd);
CSharedCriticalSection lockFactory(
commandLine.NumberOfLocks());
CPerformanceCounters counters(true, sa);
CIOPool pool( counters, commandLine.NumberOfIOThreads()); pool.Start(); CSequencedStreamSocketAllocator socketAllocator( counters, lockFactory, commandLine.SocketPoolSize()); CBufferAllocator bufferAllocator( counters, commandLine.BufferSize(), commandLine.BufferPoolSize()); const CFullAddress address( commandLine.Server(), commandLine.Port()); const ListenBacklog listenBacklog = commandLine.ListenBacklog(); CConnectionLimiter connectionLimiter(commandLine.MaxConnections()); CSocketServer server( counters, commandLine.NoWelcomeMessage() ? "" : "Welcome to echo server\r\n", address, listenBacklog, pool, socketAllocator, bufferAllocator, connectionLimiter);
void CSocketServer::OnConnectionEstablished( IStreamSocket &socket, const IAddress & /*address*/) { m_counters.OnConnectionStarted(); Output(_T("OnConnectionEstablished")); socket.Write(m_welcomeMessage.c_str(), GetStringLengthAsDWORD(m_welcomeMessage)); socket.Read(); } void CSocketServer::OnConnectionClosed( IStreamSocket & /*socket*/) { m_counters.OnConnectionComplete(); Output(_T("OnConnectionClosed")); }
void CPerformanceCounters::OnConnectionStarted() { if (m_pCounters) { m_pCounters->IncrementPerformanceCounter32(m_connectionsActiveCounter); } } void CPerformanceCounters::OnConnectionComplete() { if (m_pCounters) { m_pCounters->DecrementPerformanceCounter32(m_connectionsActiveCounter); } }
AddSupportedLanguage()
, etc. CPerformanceDataSchema::CPerformanceDataSchema() { Object &exeObject = AddObject( s_objectName, _T("The \"JetByte Echo Server\" object type defines ") _T("counters that apply to the Echo Server process as ") _T("a whole. "), DetailLevelNovice); exeObject.AddCounter( s_bytesProcessedCounter, _T("The total number of bytes processed"), DetailLevelNovice, -6, CounterTypeCounter64); exeObject.SetDefaultCounter(); exeObject.AddCounter( s_bytesPerSecondCounter, _T("The number of bytes processed per second"), DetailLevelNovice, -4, CounterTypePerSec);
CPerformanceCounters::CPerformanceCounters( const bool createCounters, CSecurityAttributes &sa) : m_pCounters(CreateCountersIfRequired(createCounters, s_applicationName, m_schema, sa)), m_object(m_pCounters ? m_pCounters->GetPerformanceObject(m_schema.s_objectName) : 0), m_bytesProcessedCounter(m_pCounters ? m_pCounters->GetPerformanceCounter(m_object, m_schema.s_bytesProcessedCounter) : 0), m_bytesPerSecondCounter(m_pCounters ? m_pCounters->GetPerformanceCounter(m_object, m_schema.s_bytesPerSecondCounter) : 0), m_totalBuffersCounter(m_pCounters ? m_pCounters->GetPerformanceCounter(m_object, m_schema.s_totalBuffersCounter) : 0), m_buffersInUseCounter(m_pCounters ? m_pCounters->GetPerformanceCounter(m_object, m_schema.s_buffersInUseCounter) : 0), m_connectionsActiveCounter(m_pCounters ? m_pCounters->GetPerformanceCounter(m_object, m_schema.s_connectionsActiveCounter) : 0), m_totalSocketsCounter(m_pCounters ? m_pCounters->GetPerformanceCounter(m_object, m_schema.s_totalSocketsCounter) : 0), m_socketsInUseCounter(m_pCounters ? m_pCounters->GetPerformanceCounter(m_object, m_schema.s_socketsInUseCounter) : 0), m_ioThreadsActiveCounter(m_pCounters ? m_pCounters->GetPerformanceCounter(m_object, m_schema.s_ioThreadsActiveCounter) : 0), m_ioThreadsProcessingCounter(m_pCounters ? m_pCounters->GetPerformanceCounter(m_object, m_schema.s_ioThreadsProcessingCounter) : 0) { }
bool CPerformanceCounters::InstallCounters() { bool installed = false; CPerformanceCounterInstaller installer; if (!installer.CountersAreInstalled(s_applicationName)) { const _tstring counterPath = GetModulePathName() + _T("\\EchoServerPerfCounters.dll"); CPerformanceDataSchema schema; CPerformanceDataSchemaFileExporter exporter; installer.Install( s_applicationName, counterPath, false, exporter.ExportHeaderFile(s_applicationName, schema), exporter.ExportIniFile(s_applicationName, schema), _T(""), 10000, 10000, schema.GetChecksum()); installed = true; } return installed; } bool CPerformanceCounters::RemoveCounters() { bool removed = false; CPerformanceCounterInstaller installer; if (installer.CountersAreInstalled(s_applicationName)) { installer.Uninstall(s_applicationName); removed = true; } return removed; }
ICollectPerformanceData *CreatePerformanceDataCollector() { CSEHException::Translator sehTranslator; try { return new CPerformanceDataCollector(s_applicationName); } catch(CException &e) { const _tstring message = _T("CreatePerformanceDataCollector() - Exception: ") + e.GetDetails(); OutputDebugString(message.c_str()); } catch(CSEHException &e) { const _tstring message = _T("CreatePerformanceDataCollector() - Exception: ") + e.GetDetails(); OutputDebugString(message.c_str()); } catch(...) { OutputDebugString(_T("CreatePerformanceDataCollector() - Unexpected exception")); } return 0; }
perfmon