From 7759ffd3c08361b52a37ee4987b5ffdd85359a57 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Fri, 17 Jan 2014 06:29:50 -0700 Subject: [PATCH] Added MetricsServer code, still needs a WinMain.cpp for windows --- .../MetricsServer/src/linux/main.cpp | 76 +++++ .../src/shared/ConfigMetricsServer.cpp | 45 +++ .../src/shared/ConfigMetricsServer.h | 89 ++++++ .../src/shared/FirstMetricsServer.cpp | 12 + .../src/shared/FirstMetricsServer.h | 19 ++ .../src/shared/MetricsGatheringConnection.cpp | 297 ++++++++++++++++++ .../src/shared/MetricsGatheringConnection.h | 48 +++ .../src/shared/MetricsServer.cpp | 210 +++++++++++++ .../MetricsServer/src/shared/MetricsServer.h | 52 +++ .../src/shared/TaskConnection.cpp | 83 +++++ .../MetricsServer/src/shared/TaskConnection.h | 39 +++ 11 files changed, 970 insertions(+) create mode 100644 engine/server/application/MetricsServer/src/linux/main.cpp create mode 100644 engine/server/application/MetricsServer/src/shared/ConfigMetricsServer.cpp create mode 100644 engine/server/application/MetricsServer/src/shared/ConfigMetricsServer.h create mode 100644 engine/server/application/MetricsServer/src/shared/FirstMetricsServer.cpp create mode 100644 engine/server/application/MetricsServer/src/shared/FirstMetricsServer.h create mode 100644 engine/server/application/MetricsServer/src/shared/MetricsGatheringConnection.cpp create mode 100644 engine/server/application/MetricsServer/src/shared/MetricsGatheringConnection.h create mode 100644 engine/server/application/MetricsServer/src/shared/MetricsServer.cpp create mode 100644 engine/server/application/MetricsServer/src/shared/MetricsServer.h create mode 100644 engine/server/application/MetricsServer/src/shared/TaskConnection.cpp create mode 100644 engine/server/application/MetricsServer/src/shared/TaskConnection.h diff --git a/engine/server/application/MetricsServer/src/linux/main.cpp b/engine/server/application/MetricsServer/src/linux/main.cpp new file mode 100644 index 00000000..2287e9de --- /dev/null +++ b/engine/server/application/MetricsServer/src/linux/main.cpp @@ -0,0 +1,76 @@ +#include "sharedFoundation/FirstSharedFoundation.h" + +#include "ConfigMetricsServer.h" +#include "MetricsServer.h" + +#include "sharedCompression/SetupSharedCompression.h" +#include "sharedDebug/SetupSharedDebug.h" +#include "sharedFile/SetupSharedFile.h" +#include "sharedFoundation/Os.h" +#include "sharedFoundation/SetupSharedFoundation.h" +#include "sharedNetwork/NetworkHandler.h" +#include "sharedNetwork/SetupSharedNetwork.h" +#include "sharedNetworkMessages/SetupSharedNetworkMessages.h" +#include "sharedRandom/SetupSharedRandom.h" +#include "sharedThread/SetupSharedThread.h" + +#include + +// ====================================================================== + +int main(int argc, char ** argv) +{ + SetupSharedThread::install(); + SetupSharedDebug::install(1024); + + //-- setup foundation + SetupSharedFoundation::Data setupFoundationData(SetupSharedFoundation::Data::D_game); + setupFoundationData.lpCmdLine = ConvertCommandLine(argc,argv); + SetupSharedFoundation::install (setupFoundationData); + + { + //SetupSharedObject::Data data; + //SetupSharedObject::setupDefaultGameData(data); + //SetupSharedObject::install(data); + } + SetupSharedCompression::install(); + SetupSharedFile::install(32); + + SetupSharedNetwork::SetupData networkSetupData; + SetupSharedNetwork::getDefaultServerSetupData(networkSetupData); + SetupSharedNetwork::install(networkSetupData); + + SetupSharedRandom::install(static_cast(time(NULL))); //lint !e1924 !e64 // NULL is a C-Style cast? + + Os::setProgramName("MetricsServer"); + //setup the server + ConfigMetricsServer::install(); + + //set command line + std::string cmdLine = setupFoundationData.lpCmdLine; + size_t firstArg = cmdLine.find(" ", 0); + size_t lastSlash = 0; + size_t nextSlash = 0; + while(nextSlash < firstArg) + { + nextSlash = cmdLine.find("/", lastSlash); + if(nextSlash == cmdLine.npos || nextSlash >= firstArg) //lint !e1705 static class members may be accessed by the scoping operator (huh?) + break; + lastSlash = nextSlash + 1; + } + cmdLine = cmdLine.substr(lastSlash); + MetricsServer::setCommandLine(cmdLine); + + + //-- run game + NetworkHandler::install(); + MetricsServer::install(); + MetricsServer::run(); + MetricsServer::remove(); + NetworkHandler::remove(); + SetupSharedFoundation::remove(); + + return 0; +} + + diff --git a/engine/server/application/MetricsServer/src/shared/ConfigMetricsServer.cpp b/engine/server/application/MetricsServer/src/shared/ConfigMetricsServer.cpp new file mode 100644 index 00000000..469d7efe --- /dev/null +++ b/engine/server/application/MetricsServer/src/shared/ConfigMetricsServer.cpp @@ -0,0 +1,45 @@ +// ConfigMetricsServer.cpp +// copyright 2000 Verant Interactive +// Author: Justin Randall + + +//----------------------------------------------------------------------- + +#include "FirstMetricsServer.h" +#include "sharedFoundation/ConfigFile.h" +#include "ConfigMetricsServer.h" + +//----------------------------------------------------------------------- + +ConfigMetricsServer::Data * ConfigMetricsServer::data = 0; + +#define KEY_INT(a,b) (data->a = ConfigFile::getKeyInt("MetricsServer", #a, b)) +#define KEY_BOOL(a,b) (data->a = ConfigFile::getKeyBool("MetricsServer", #a, b)) +#define KEY_REAL(a,b) (data->a = ConfigFile::getKeyReal("MetricsServer", #a, b)) +#define KEY_STRING(a,b) (data->a = ConfigFile::getKeyString("MetricsServer", #a, b)) + +//----------------------------------------------------------------------- + +void ConfigMetricsServer::install(void) +{ + data = new ConfigMetricsServer::Data; + + KEY_STRING(authenticationFileName, "../../exe/shared/metricsAuthentication.cfg"); + KEY_STRING(clusterName, "DevCluster"); + KEY_INT(metricsListenerPort, 2200); + KEY_INT(metricsServicePort, 44480); + KEY_BOOL(runTestStats, false); + KEY_INT(taskManagerPort, 60001); + KEY_STRING(metricsServiceBindInterface, ""); +} + +//----------------------------------------------------------------------- + +void ConfigMetricsServer::remove(void) +{ + delete data; + data = 0; +} + +//----------------------------------------------------------------------- + diff --git a/engine/server/application/MetricsServer/src/shared/ConfigMetricsServer.h b/engine/server/application/MetricsServer/src/shared/ConfigMetricsServer.h new file mode 100644 index 00000000..14819799 --- /dev/null +++ b/engine/server/application/MetricsServer/src/shared/ConfigMetricsServer.h @@ -0,0 +1,89 @@ +// ConfigMetricsServer.h +// copyright 2000 Verant Interactive +// Author: Justin Randall + +#ifndef _ConfigMetricsServer_H +#define _ConfigMetricsServer_H + +//----------------------------------------------------------------------- + +class ConfigMetricsServer +{ +public: + struct Data + { + const char * authenticationFileName; + const char * clusterName; + uint16 metricsListenerPort; + uint16 metricsServicePort; + bool runTestStats; + uint16 taskManagerPort; + const char * metricsServiceBindInterface; + }; + + static void install (); + static void remove (); + + + static const char* getAuthenticationFileName(); + static const char* getClusterName(); + static uint16 getMetricsListenerPort(); + static uint16 getMetricsServicePort(); + static bool getRunTestStats(); + static uint16 getTaskManagerPort(); + static const char* getMetricsServiceBindInterface(); + +private: + static Data * data; +}; + +//----------------------------------------------------------------------- + +inline const char* ConfigMetricsServer::getAuthenticationFileName() +{ + return data->authenticationFileName; +} +//----------------------------------------------------------------------- + +inline const char* ConfigMetricsServer::getClusterName() +{ + return data->clusterName; +} +//----------------------------------------------------------------------- + +inline uint16 ConfigMetricsServer::getMetricsListenerPort() +{ + return data->metricsListenerPort; +} +//----------------------------------------------------------------------- + +inline uint16 ConfigMetricsServer::getMetricsServicePort() +{ + return data->metricsServicePort; +} +//----------------------------------------------------------------------- + +inline bool ConfigMetricsServer::getRunTestStats() +{ + return data->runTestStats; +} +//----------------------------------------------------------------------- + +inline uint16 ConfigMetricsServer::getTaskManagerPort() +{ + return data->taskManagerPort; +} + +//----------------------------------------------------------------------- + +inline const char * ConfigMetricsServer::getMetricsServiceBindInterface() +{ + return data->metricsServiceBindInterface; +} + +//----------------------------------------------------------------------- + + +#endif // _ConfigMetricsServer_H + + diff --git a/engine/server/application/MetricsServer/src/shared/FirstMetricsServer.cpp b/engine/server/application/MetricsServer/src/shared/FirstMetricsServer.cpp new file mode 100644 index 00000000..f0b7dbe3 --- /dev/null +++ b/engine/server/application/MetricsServer/src/shared/FirstMetricsServer.cpp @@ -0,0 +1,12 @@ +// FirstChatServer.cpp +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +//----------------------------------------------------------------------- + +#include "FirstMetricsServer.h" + +//----------------------------------------------------------------------- + +// satisfy strangeness with MS if there are no other files included in the PCH +void FirstMetricsServerFoo(){} diff --git a/engine/server/application/MetricsServer/src/shared/FirstMetricsServer.h b/engine/server/application/MetricsServer/src/shared/FirstMetricsServer.h new file mode 100644 index 00000000..e4b9c5dc --- /dev/null +++ b/engine/server/application/MetricsServer/src/shared/FirstMetricsServer.h @@ -0,0 +1,19 @@ +// FirstMetricsServer.h +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +#ifndef _INCLUDED_FirstMetricsServer_H +#define _INCLUDED_FirstMetricsServer_H + +//----------------------------------------------------------------------- + +#pragma warning ( disable : 4702 ) + +#include "Archive/ByteStream.h" +#include "sharedFoundation/FirstSharedFoundation.h" +#include "sharedFoundation/NetworkId.h" +#include "sharedNetwork/Connection.h" + +//----------------------------------------------------------------------- + +#endif // _INCLUDED_FirstChatServer_H diff --git a/engine/server/application/MetricsServer/src/shared/MetricsGatheringConnection.cpp b/engine/server/application/MetricsServer/src/shared/MetricsGatheringConnection.cpp new file mode 100644 index 00000000..df7c7fe5 --- /dev/null +++ b/engine/server/application/MetricsServer/src/shared/MetricsGatheringConnection.cpp @@ -0,0 +1,297 @@ +// MetricsGatheringConnection.cpp +// Copyright 2000-2002 Sony Online Entertainment + + +#include "FirstMetricsServer.h" +#include "MetricsGatheringConnection.h" + +#include "ConfigMetricsServer.h" +#include "MetricsServer.h" +#include "MonAPI2/MonitorAPI.h" +#include "serverNetworkMessages/MetricsInitiationMessage.h" + +//----------------------------------------------------------------------- + +std::map MetricsGatheringConnection::ms_metricsSummaryTotalVal; + +namespace MetricsGatheringConnectionNamespace +{ + int s_masterChannelIndex = 1; + std::map s_masterGraphMap; +}; + +using namespace MetricsGatheringConnectionNamespace; + +//----------------------------------------------------------------------- + +MetricsGatheringConnection::MetricsGatheringConnection(UdpConnectionMT * u, TcpClient * t) : + ServerConnection(u, t), + m_initialized(false), + m_label(), + m_processIndex(0), + m_processLabel(), + m_metricsChannels() +{ + m_label = ""; + m_processLabel = ""; +} + +//----------------------------------------------------------------------- + +MetricsGatheringConnection::~MetricsGatheringConnection() +{ + +} + +//----------------------------------------------------------------------- + + + +void MetricsGatheringConnection::onConnectionClosed() +{ + m_initialized = false; + DEBUG_REPORT_LOG(true, ("Metrics Connection with Server %s closed\n", m_processLabel.c_str())); + CMonitorAPI * mon = MetricsServer::getMonitor(); + NOT_NULL(mon); + + if (m_processLabel == "CentralServer") + { + mon->set(MetricsServer::getWorldCountChannel(), STATUS_DOWN); + } + + remove(); +} + +//----------------------------------------------------------------------- + +void MetricsGatheringConnection::onConnectionOpened() +{ + DEBUG_REPORT_LOG(true, ("Metrics Connection with Server opened\n")); +} + +//----------------------------------------------------------------------- + +void MetricsGatheringConnection::onReceive(const Archive::ByteStream & message) +{ + Archive::ReadIterator ri = message.begin(); + GameNetworkMessage m(ri); + ri = message.begin(); + + if(m.isType("ConnectionServerMetricsMessage")) + { + DEBUG_FATAL(true, ("This message has been depricated")); + } + else if (m.isType("MetricsInitiationMessage")) + { + WARNING_STRICT_FATAL(m_initialized, ("Received initialize metrics on initialized connection")); + //Get process name and secondary field (i.e. planet) + MetricsInitiationMessage mx(ri); + bool dynamic = mx.getIsDynamic(); + std::string process = mx.getPrimaryName(); + std::string planet = mx.getSecondaryName(); + int index = mx.getIndex(); + initialize(process, planet, dynamic, index); + } + else if (m.isType("MetricsDataMessage")) + { + if (!m_initialized) + { + //Received data on uninitialized connection. + return; + } + MetricsDataMessage metricsData(ri); + update(metricsData.getData()); + } + else + { + ServerConnection::onReceive(message); + } +} + +//----------------------------------------------------------------------- + +void MetricsGatheringConnection::initialize(const std::string & process, const std::string & planet, bool numberedProcess, int index) +{ + const std::string dot = "."; + m_label = process; + if (planet != "") + m_label = m_label + dot + planet; + + m_processLabel = m_label; + if (numberedProcess) + { + m_processIndex = index; + char tmpBuf[100]; + m_label = m_label + dot + _itoa(m_processIndex, tmpBuf, 10); + + } + m_label = m_label + dot; + m_metricsChannels.clear(); + m_initialized = true; +} + +//----------------------------------------------------------------------- + +void MetricsGatheringConnection::update(const std::vector & data) +{ + CMonitorAPI * mon = MetricsServer::getMonitor(); + NOT_NULL(mon); + + std::vector::const_iterator dataIter = data.begin(); + for(; dataIter != data.end(); ++dataIter) + { + std::map >::iterator i = m_metricsChannels.find((*dataIter).m_label); + if (i == m_metricsChannels.end()) + { + //If this is the first update for a metrics label, we need to assign it a channel number. + //Then add it to the montior + int newChannel = 0; + std::string graphName = m_label + ((*dataIter).m_label); + if ( dataIter->m_summary ) + graphName = ((*dataIter).m_label); + std::map::iterator graphIter = s_masterGraphMap.find(graphName); + if (graphIter != s_masterGraphMap.end()) + { + newChannel = graphIter->second; + } + else + { + newChannel = ++s_masterChannelIndex; + s_masterGraphMap[graphName] = newChannel; + int ping = MON_HISTORY; + if(! dataIter->m_persistData) + ping = MON_ONLY_SHOW; + mon->add(const_cast(graphName.c_str()), newChannel, ping); + } + m_metricsChannels[(*dataIter).m_label] = std::make_pair(graphName, newChannel); + mon->set(newChannel, (*dataIter).m_value); + + //note: we know that the "isSecret", and "isLocked" nodes will come after the "population" node in the list + // we are iterating over, so they will override the population setting + if (strstr((*dataIter).m_label.c_str(), "population") != NULL) + { + // there are nodes under the population node, so don't interpret them as the population + if (strstr((*dataIter).m_label.c_str(), "population.") == NULL) + mon->set(MetricsServer::getWorldCountChannel(), std::max((*dataIter).m_value, 0)); + } + else if (strstr((*dataIter).m_label.c_str(), "isSecret") != NULL + || strstr((*dataIter).m_label.c_str(), "isLocked") != NULL) + { + if ((*dataIter).m_value == 1) + mon->set(MetricsServer::getWorldCountChannel(), STATUS_LOCKED); + } + else if (strstr((*dataIter).m_label.c_str(), "isLoading") != NULL) + { + // include in the root node description how + // long the cluster has been loading + if ((*dataIter).m_value > 0) + { + char buffer[128]; + snprintf(buffer, sizeof(buffer)-1, "(isLoading: %d seconds) ", (*dataIter).m_value); + buffer[sizeof(buffer)-1] = '\0'; + + std::string description = buffer; + description += MetricsServer::getWorldCountChannelDescription(); + mon->setDescription(MetricsServer::getWorldCountChannel(), description.c_str()); + } + else + { + mon->setDescription(MetricsServer::getWorldCountChannel(), MetricsServer::getWorldCountChannelDescription().c_str()); + } + } + + mon->setDescription(newChannel, (*dataIter).m_description.c_str()); + } + else + { + if ( dataIter->m_summary ) + { + int val = (*dataIter).m_value; + if ( val < 0 ) + val = 0; + int i_delta = val - m_metricsSummaryMyVal[ (*dataIter).m_label ]; + ms_metricsSummaryTotalVal[ (*dataIter).m_label ] += i_delta; + m_metricsSummaryMyVal[ (*dataIter).m_label ] = val; + + val = ms_metricsSummaryTotalVal[ (*dataIter).m_label ]; // Don't go below 0 (shouldn't happen) + if ( val < 0 ) + val = 0; + mon->set(i->second.second, val ); + } + else + { + mon->set(i->second.second, (*dataIter).m_value); + } + + //note: we know that the "isSecret", and "isLocked" nodes will come after the "population" node in the list + // we are iterating over, so they will override the population setting + if (strstr((*dataIter).m_label.c_str(), "population") != NULL) + { + // there are nodes under the population node, so don't interpret them as the population + if (strstr((*dataIter).m_label.c_str(), "population.") == NULL) + mon->set(MetricsServer::getWorldCountChannel(), std::max((*dataIter).m_value, 0)); + } + else if (strstr((*dataIter).m_label.c_str(), "isSecret") != NULL + || strstr((*dataIter).m_label.c_str(), "isLocked") != NULL) + { + if ((*dataIter).m_value == 1) + mon->set(MetricsServer::getWorldCountChannel(), STATUS_LOCKED); + } + else if (strstr((*dataIter).m_label.c_str(), "isLoading") != NULL) + { + // include in the root node description how + // long the cluster has been loading + if ((*dataIter).m_value > 0) + { + char buffer[128]; + snprintf(buffer, sizeof(buffer)-1, "(isLoading: %d seconds) ", (*dataIter).m_value); + buffer[sizeof(buffer)-1] = '\0'; + + std::string description = buffer; + description += MetricsServer::getWorldCountChannelDescription(); + mon->setDescription(MetricsServer::getWorldCountChannel(), description.c_str()); + } + else + { + mon->setDescription(MetricsServer::getWorldCountChannel(), MetricsServer::getWorldCountChannelDescription().c_str()); + } + } + + mon->setDescription(i->second.second, (*dataIter).m_description.c_str()); + } + } +} + + +//----------------------------------------------------------------------- + +void MetricsGatheringConnection::remove() +{ + CMonitorAPI * mon = MetricsServer::getMonitor(); + NOT_NULL(mon); + std::map >::iterator i = m_metricsChannels.begin(); + for (; i != m_metricsChannels.end(); ++i) + { + if ( ms_metricsSummaryTotalVal.count( i->first ) ) // summary of multiple servers data + { + // This is a summary entry, we can't remove it, just factor our info out of the total + ms_metricsSummaryTotalVal[ i->first ] -= m_metricsSummaryMyVal[ i->first ]; + m_metricsSummaryMyVal[ i->first ] = 0; + mon->set(i->second.second, ms_metricsSummaryTotalVal[ i->first ] ); + } + else if (m_processIndex) + { + mon->set(i->second.second, STATUS_LOADING); + } + else + { + mon->remove(i->second.second); + IGNORE_RETURN(s_masterGraphMap.erase(i->second.first)); + } + } + + if(! m_processIndex) + m_metricsChannels.clear(); +} + +//----------------------------------------------------------------------- diff --git a/engine/server/application/MetricsServer/src/shared/MetricsGatheringConnection.h b/engine/server/application/MetricsServer/src/shared/MetricsGatheringConnection.h new file mode 100644 index 00000000..2cf45cdf --- /dev/null +++ b/engine/server/application/MetricsServer/src/shared/MetricsGatheringConnection.h @@ -0,0 +1,48 @@ +// MetricsGatheringConnection.h +// Copyright 2000-2002 Sony Online Entertainment + +#ifndef _MetricsGatheringConnection_H_ +#define _MetricsGatheringConnection_H_ + +#include "serverUtility/ServerConnection.h" + +#include "serverNetworkMessages/MetricsDataMessage.h" + +#include +#include +#include + +//----------------------------------------------------------------------- + +class MetricsGatheringConnection : public ServerConnection +{ +public: + MetricsGatheringConnection(UdpConnectionMT * u, TcpClient *); + virtual ~MetricsGatheringConnection(); + + virtual void onConnectionClosed(); + virtual void onConnectionOpened(); + virtual void onReceive(const Archive::ByteStream & message); + +private: + MetricsGatheringConnection(); + MetricsGatheringConnection(const MetricsGatheringConnection&); + MetricsGatheringConnection& operator= (const MetricsGatheringConnection&); + + void initialize(const std::string &, const std::string &, bool, const int); + void remove(); + void update(const std::vector & data); + + bool m_initialized; + std::string m_label; + int m_processIndex; + std::string m_processLabel; + + std::map > m_metricsChannels; + + static std::map ms_metricsSummaryTotalVal; + std::map m_metricsSummaryMyVal; +}; + + +#endif diff --git a/engine/server/application/MetricsServer/src/shared/MetricsServer.cpp b/engine/server/application/MetricsServer/src/shared/MetricsServer.cpp new file mode 100644 index 00000000..72c9ea22 --- /dev/null +++ b/engine/server/application/MetricsServer/src/shared/MetricsServer.cpp @@ -0,0 +1,210 @@ + + +#include "FirstMetricsServer.h" +#include "MetricsServer.h" + +#include "ConfigMetricsServer.h" +#include "MetricsGatheringConnection.h" +#include "TaskConnection.h" + +#include "sharedFoundation/ApplicationVersion.h" +#include "sharedFoundation/Clock.h" +#include "sharedFoundation/Os.h" +#include "sharedNetwork/Connection.h" +#include "sharedNetwork/NetworkSetupData.h" +#include "sharedNetwork/Service.h" + +#include "MonAPI2/MonitorAPI.h" + +#ifdef LINUX +#include +#endif + +//---------------------------------------------------------------- +std::string MetricsServer::m_commandLine; +int MetricsServer::m_worldCountChannel = 0; +std::string MetricsServer::m_worldCountChannelDescription; +bool MetricsServer::m_done = false; +Service* MetricsServer::m_metricsService; +CMonitorAPI * MetricsServer::m_soeMonitor; +Service * MetricsServer::ms_service = NULL; +TaskConnection * MetricsServer::ms_taskConnection = NULL; + +//---------------------------------------------------------------- + +namespace MetricsServerNamespace +{ + const char* getDateString() + { +#ifdef LINUX + time_t timeV; + time(&timeV); + return ctime(&timeV); +#else + return "no time available"; +#endif + } +}; + +using namespace MetricsServerNamespace; + +//---------------------------------------------------------------- + +MetricsServer::MetricsServer() +{ +} + +//---------------------------------------------------------------- + + +MetricsServer::~MetricsServer() +{ +} + +//---------------------------------------------------------------- + +CMonitorAPI * MetricsServer::getMonitor() +{ + return m_soeMonitor; +} + +//---------------------------------------------------------------- + +int MetricsServer::getWorldCountChannel() +{ + return m_worldCountChannel; +} + +//---------------------------------------------------------------- + +const std::string & MetricsServer::getWorldCountChannelDescription() +{ + return m_worldCountChannelDescription; +} + +//---------------------------------------------------------------- + +void MetricsServer::install() +{ + // Must be called before initMonitor() on Win32 + NetworkSetupData setup; + setup.port = ConfigMetricsServer::getMetricsServicePort(); + setup.maxConnections = 200; + setup.bindInterface = ConfigMetricsServer::getMetricsServiceBindInterface(); + Service * ms_service; + ms_service = new Service(ConnectionAllocator(), setup); + + // connect to the task manager + ms_taskConnection = new TaskConnection("127.0.0.1", ConfigMetricsServer::getTaskManagerPort()); + + // load authentication data and bind the monitor to the port + m_soeMonitor = new CMonitorAPI("metricsAuthentication.cfg", ConfigMetricsServer::getMetricsListenerPort()); + + const char *masterChannel = "Population"; + m_worldCountChannel = 0; + m_soeMonitor->add(masterChannel, m_worldCountChannel); + char tmpBuf[512]; + std::string host = NetworkHandler::getHumanReadableHostName().c_str(); + size_t dotPos = host.find("."); + if(dotPos != host.npos) + { + host = host.substr(0, dotPos); + } + + snprintf(tmpBuf, sizeof(tmpBuf), "version %s on %s [%s]", ApplicationVersion::getInternalVersion(), host.c_str(), getDateString()); + m_worldCountChannelDescription = tmpBuf; + m_soeMonitor->setDescription(MetricsServer::getWorldCountChannel(), tmpBuf); + + //BEGIN TEST CODE + if (ConfigMetricsServer::getRunTestStats()) + { + m_soeMonitor->add("TestStats.PlanetServer.Zandar.Count", 10000); + m_soeMonitor->add("TestStats.GameServer.Zandar.1.Count", 10001); + m_soeMonitor->add("TestStats.GameServer.Zandar.2.Count", 10002); + } + //END TEST CODE +} + +//---------------------------------------------------------------- + +void MetricsServer::remove() +{ + + delete m_soeMonitor; + m_soeMonitor = 0; + if(ms_taskConnection) + ms_taskConnection->disconnect(); + delete ms_service; +} + +//---------------------------------------------------------------- + +void MetricsServer::run() +{ + Clock::setFrameRateLimit(1.0f); + int nCount= 0; + int nConnected = 0; + int nlogin = 0; + + + unsigned long initialTime = Clock::timeMs(); + bool okToUpdate = false; + + while(m_soeMonitor) + { + NetworkHandler::update(); + NetworkHandler::dispatch(); + if (!Os::update()) + break; + + // updateMonitor() will return false on the + // next update cyclte following a call to shutdownMonitor() + if (okToUpdate) + { + m_soeMonitor->Update(); + } + else + { + //Don't start updating the MonApi until a minute after startup + if (Clock::timeMs() - initialTime > 60000) + { + okToUpdate = true; + } + } + + // Update the counts in the object + // Test data + + // Test data + if (ConfigMetricsServer::getRunTestStats()) + { + + m_soeMonitor->set(10000, nCount++); + m_soeMonitor->set(10001, nConnected++); + m_soeMonitor->set(10002, nlogin++); + } + + static bool pDump = false; + if (pDump) + m_soeMonitor->dump(); + Clock::limitFrameRate(); + usleep(2000); + } +} + +//---------------------------------------------------------------- + +const std::string & MetricsServer::getCommandLine() +{ + return m_commandLine; +} + +//---------------------------------------------------------------- + +void MetricsServer::setCommandLine(const std::string & s) +{ + m_commandLine = s; +} + +//---------------------------------------------------------------- + diff --git a/engine/server/application/MetricsServer/src/shared/MetricsServer.h b/engine/server/application/MetricsServer/src/shared/MetricsServer.h new file mode 100644 index 00000000..9b135868 --- /dev/null +++ b/engine/server/application/MetricsServer/src/shared/MetricsServer.h @@ -0,0 +1,52 @@ +// MetricsServer.h +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +#ifndef _INCLUDED_MetricsServer_H +#define _INCLUDED_MetricsServer_H + +//----------------------------------------------------------------------- + +class CMonitorAPI; +class Service; +class TaskConnection; + +//----------------------------------------------------------------------- + +class MetricsServer +{ +public: + MetricsServer(); + ~MetricsServer(); + + static void install(); + static void remove(); + static void run (); + + static CMonitorAPI * getMonitor(); + static const std::string & getCommandLine(); + static void setCommandLine(const std::string & ); + static int getWorldCountChannel(); + static const std::string & getWorldCountChannelDescription(); + +private: + MetricsServer & operator = (const MetricsServer & rhs); + MetricsServer(const MetricsServer & source); + +private: + static int m_worldCountChannel; + static std::string m_worldCountChannelDescription; + static std::string m_commandLine; + static bool m_done; + static Service * m_metricsService; + static CMonitorAPI * m_soeMonitor; + static Service * ms_service; + static TaskConnection * ms_taskConnection; +}; +//----------------------------------------------------------------------- + + + +//----------------------------------------------------------------------- + +#endif // _INCLUDED_MetricsServer_H diff --git a/engine/server/application/MetricsServer/src/shared/TaskConnection.cpp b/engine/server/application/MetricsServer/src/shared/TaskConnection.cpp new file mode 100644 index 00000000..c3a6d841 --- /dev/null +++ b/engine/server/application/MetricsServer/src/shared/TaskConnection.cpp @@ -0,0 +1,83 @@ +// TaskConnection.cpp +// copyright 2000 Verant Interactive +// Author: Justin Randall + + +//----------------------------------------------------------------------- + +#include "FirstMetricsServer.h" +#include "TaskConnection.h" + +#include "ConfigMetricsServer.h" +#include "MetricsServer.h" +#include "serverNetworkMessages/TaskConnectionIdMessage.h" +#include "sharedFoundation/ConfigFile.h" +#include "sharedNetwork/NetworkSetupData.h" + +//----------------------------------------------------------------------- + +TaskConnection::TaskConnection(const std::string & a, const unsigned short p) : +ServerConnection(a, p, NetworkSetupData()) +{ +} + +//----------------------------------------------------------------------- + +TaskConnection::TaskConnection(UdpConnectionMT * u, TcpClient * t) : +ServerConnection(u, t) +{ +} + +//----------------------------------------------------------------------- + +TaskConnection::~TaskConnection() +{ +} + +//----------------------------------------------------------------------- + +void TaskConnection::onConnectionClosed() +{ +} + +//----------------------------------------------------------------------- + +void TaskConnection::onConnectionOpened() +{ + std::string cmdLine = MetricsServer::getCommandLine(); + // fix up path + size_t last = 0; + while(cmdLine.find_first_of("\\", last + 1) < cmdLine.size()) + last = cmdLine.find_first_of("\\", last + 1); + cmdLine = cmdLine.substr(last); + + // get cluster name + std::string clusterName; + ConfigFile::Section const * const sec = ConfigFile::getSection("TaskManager"); + if (sec) + { + ConfigFile::Key const * const ky = sec->findKey("clusterName"); + if (ky) + { + clusterName = ky->getAsString(ky->getCount()-1, ""); + } + } + + TaskConnectionIdMessage id(TaskConnectionIdMessage::Metrics, cmdLine, clusterName); + send(id, true); +} + +//----------------------------------------------------------------------- + +void TaskConnection::onReceive(const Archive::ByteStream & message) +{ + UNREF(message); +#if 0 + Archive::ReadIterator r(message); + GameNetworkMessage m(r); +#endif +} + +//----------------------------------------------------------------------- + + diff --git a/engine/server/application/MetricsServer/src/shared/TaskConnection.h b/engine/server/application/MetricsServer/src/shared/TaskConnection.h new file mode 100644 index 00000000..4372fa92 --- /dev/null +++ b/engine/server/application/MetricsServer/src/shared/TaskConnection.h @@ -0,0 +1,39 @@ +// TaskConnection.h +// copyright 2001 Verant Interactive +// Author: Justin Randall + +#ifndef _TaskConnection_H +#define _TaskConnection_H + +//----------------------------------------------------------------------- + +class TaskCommandChannel; + +#include "serverUtility/ServerConnection.h" + +//----------------------------------------------------------------------- + +class TaskConnection : public ServerConnection +{ +public: + TaskConnection(const std::string & remoteAddress, const unsigned short remotePort); + TaskConnection(UdpConnectionMT * u, TcpClient *); + ~TaskConnection(); + + void onConnectionClosed(); + void onConnectionOpened(); + void onReceive(const Archive::ByteStream & message); + + +private: + TaskConnection(const TaskConnection&); + TaskConnection& operator= (const TaskConnection&); + + +}; //lint !e1712 default constructor not defined + +//----------------------------------------------------------------------- + +#endif // _TaskConnection_H + +