Store server statistics data in a log file and reload it when the server is restarted.

This commit is contained in:
lotodore
2007-11-11 15:58:35 +00:00
parent da559c8d88
commit d905359251
6 changed files with 127 additions and 32 deletions
+5 -1
View File
@@ -69,10 +69,14 @@ enum Button {
struct ServerStats struct ServerStats
{ {
ServerStats() : numberOfPlayersOnServer(0), totalPlayersEverLoggedIn(0), totalGamesEverStarted(0) {} ServerStats()
: numberOfPlayersOnServer(0), totalPlayersEverLoggedIn(0), totalGamesEverStarted(0),
maxGamesRunning(0), maxPlayersLoggedIn(0) {}
unsigned numberOfPlayersOnServer; unsigned numberOfPlayersOnServer;
unsigned totalPlayersEverLoggedIn; unsigned totalPlayersEverLoggedIn;
unsigned totalGamesEverStarted; unsigned totalGamesEverStarted;
unsigned maxGamesRunning;
unsigned maxPlayersLoggedIn;
}; };
#endif #endif
+2 -2
View File
@@ -44,7 +44,7 @@ ServerAcceptThread::~ServerAcceptThread()
} }
void void
ServerAcceptThread::Init(unsigned serverPort, bool ipv6, bool sctp, const std::string &pwd) ServerAcceptThread::Init(unsigned serverPort, bool ipv6, bool sctp, const string &pwd, const string &logDir)
{ {
if (IsRunning()) if (IsRunning())
{ {
@@ -60,7 +60,7 @@ ServerAcceptThread::Init(unsigned serverPort, bool ipv6, bool sctp, const std::s
context.SetAddrFamily(socket_has_dual_stack() ? AF_INET6 : (ipv6 ? AF_INET6 : AF_INET)); context.SetAddrFamily(socket_has_dual_stack() ? AF_INET6 : (ipv6 ? AF_INET6 : AF_INET));
context.SetServerPort(serverPort); context.SetServerPort(serverPort);
GetLobbyThread().Init(pwd); GetLobbyThread().Init(pwd, logDir);
} }
ServerCallback & ServerCallback &
+107 -22
View File
@@ -28,14 +28,23 @@
#include <core/loghelper.h> #include <core/loghelper.h>
#include <openssl/rand.h> #include <openssl/rand.h>
#include <fstream>
#include <boost/lambda/lambda.hpp> #include <boost/lambda/lambda.hpp>
#include <boost/filesystem.hpp>
#define SERVER_MAX_NUM_SESSIONS 512 // Maximum number of idle users in lobby. #define SERVER_MAX_NUM_SESSIONS 512 // Maximum number of idle users in lobby.
#define SERVER_CACHE_CLEANUP_INTERVAL_SEC 86400 // 1 day #define SERVER_CACHE_CLEANUP_INTERVAL_SEC 86400 // 1 day
#define SERVER_SAVE_STATISTICS_INTERVAL_SEC 60
#define SERVER_INIT_SESSION_TIMEOUT_SEC 20 #define SERVER_INIT_SESSION_TIMEOUT_SEC 20
#define SERVER_COMPUTER_PLAYER_NAME "Computer" #define SERVER_COMPUTER_PLAYER_NAME "Computer"
#define SERVER_STATISTICS_FILE_NAME "server_statistics.log"
#define SERVER_STATISTICS_STR_TOTAL_PLAYERS "TotalNumPlayersLoggedIn"
#define SERVER_STATISTICS_STR_TOTAL_GAMES "TotalNumGamesStarted"
#define SERVER_STATISTICS_STR_MAX_GAMES "MaxGamesRunning"
#define SERVER_STATISTICS_STR_MAX_PLAYERS "MaxPlayersLoggedIn"
using namespace std; using namespace std;
@@ -60,7 +69,7 @@ private:
ServerLobbyThread::ServerLobbyThread(GuiInterface &gui, ConfigFile *playerConfig, AvatarManager &avatarManager) ServerLobbyThread::ServerLobbyThread(GuiInterface &gui, ConfigFile *playerConfig, AvatarManager &avatarManager)
: m_gui(gui), m_avatarManager(avatarManager), m_playerConfig(playerConfig), : m_gui(gui), m_avatarManager(avatarManager), m_playerConfig(playerConfig),
m_curGameId(0), m_curUniquePlayerId(0), m_curSessionId(INVALID_SESSION + 1), m_curGameId(0), m_curUniquePlayerId(0), m_curSessionId(INVALID_SESSION + 1),
m_totalPlayersLoggedIn(0), m_totalGamesStarted(0) m_statDataChanged(false)
{ {
m_senderCallback.reset(new ServerSenderCallback(*this)); m_senderCallback.reset(new ServerSenderCallback(*this));
m_sender.reset(new SenderThread(GetSenderCallback())); m_sender.reset(new SenderThread(GetSenderCallback()));
@@ -73,9 +82,20 @@ ServerLobbyThread::~ServerLobbyThread()
} }
void void
ServerLobbyThread::Init(const string &pwd) ServerLobbyThread::Init(const string &pwd, const string &logDir)
{ {
m_password = pwd; m_password = pwd;
// Read previous server statistics.
if (!logDir.empty())
{
boost::filesystem::path logPath(logDir);
if (!logDir.empty())
{
logPath /= SERVER_STATISTICS_FILE_NAME;
m_statisticsFileName = logPath.directory_string();
ReadStatisticsFile();
}
}
} }
void void
@@ -129,7 +149,7 @@ ServerLobbyThread::CloseSession(SessionWrapper session)
m_gameSessionManager.RemoveSession(session.sessionData->GetId()); m_gameSessionManager.RemoveSession(session.sessionData->GetId());
// Update stats (if needed). // Update stats (if needed).
BroadcastStatisticsUpdate(); UpdateStatisticsNumberOfPlayers();
} }
void void
@@ -177,6 +197,14 @@ ServerLobbyThread::NotifyStartingGame(unsigned gameId)
boost::shared_ptr<NetPacket> packet = CreateNetPacketGameListUpdate(gameId, GAME_MODE_STARTED); boost::shared_ptr<NetPacket> packet = CreateNetPacketGameListUpdate(gameId, GAME_MODE_STARTED);
m_sessionManager.SendToAllSessionsLowPrio(GetSender(), packet, SessionData::Established); m_sessionManager.SendToAllSessionsLowPrio(GetSender(), packet, SessionData::Established);
m_gameSessionManager.SendToAllSessionsLowPrio(GetSender(), packet, SessionData::Game); m_gameSessionManager.SendToAllSessionsLowPrio(GetSender(), packet, SessionData::Game);
{
boost::mutex::scoped_lock lock(m_statMutex);
++m_statData.totalGamesEverStarted;
if (m_statData.totalGamesEverStarted > m_statData.maxGamesRunning)
m_statData.maxGamesRunning = m_statData.totalGamesEverStarted;
m_statDataChanged = true;
}
} }
void void
@@ -262,6 +290,8 @@ ServerLobbyThread::Main()
RemoveGameLoop(); RemoveGameLoop();
// Cleanup cache. // Cleanup cache.
CleanupAvatarCache(); CleanupAvatarCache();
// Save statistics if needed.
SaveStatisticsFile();
} }
} catch (const PokerTHException &e) } catch (const PokerTHException &e)
{ {
@@ -632,10 +662,10 @@ ServerLobbyThread::EstablishSession(SessionWrapper session)
{ {
boost::mutex::scoped_lock lock(m_statMutex); boost::mutex::scoped_lock lock(m_statMutex);
++m_totalPlayersLoggedIn; ++m_statData.totalPlayersEverLoggedIn;
m_statDataChanged = true;
} }
UpdateStatisticsNumberOfPlayers();
BroadcastStatisticsUpdate();
} }
void void
@@ -753,12 +783,6 @@ ServerLobbyThread::InternalAddGame(boost::shared_ptr<ServerGameThread> game)
// Notify all players. // Notify all players.
m_sessionManager.SendToAllSessionsLowPrio(GetSender(), CreateNetPacketGameListNew(*game), SessionData::Established); m_sessionManager.SendToAllSessionsLowPrio(GetSender(), CreateNetPacketGameListNew(*game), SessionData::Established);
m_gameSessionManager.SendToAllSessionsLowPrio(GetSender(), CreateNetPacketGameListNew(*game), SessionData::Game); m_gameSessionManager.SendToAllSessionsLowPrio(GetSender(), CreateNetPacketGameListNew(*game), SessionData::Game);
{
boost::mutex::scoped_lock lock(m_statMutex);
++m_totalGamesStarted;
}
BroadcastStatisticsUpdate();
} }
void void
@@ -891,23 +915,32 @@ ServerLobbyThread::SendGameList(boost::shared_ptr<SessionData> s)
} }
void void
ServerLobbyThread::BroadcastStatisticsUpdate() ServerLobbyThread::UpdateStatisticsNumberOfPlayers()
{ {
boost::shared_ptr<NetPacket> packet(new NetPacketStatisticsChanged); ServerStats stats;
NetPacketStatisticsChanged::Data statData;
unsigned curNumberOfPlayersOnServer = m_sessionManager.GetRawSessionCount() + m_gameSessionManager.GetRawSessionCount(); unsigned curNumberOfPlayersOnServer = m_sessionManager.GetRawSessionCount() + m_gameSessionManager.GetRawSessionCount();
{ {
boost::mutex::scoped_lock lock(m_statMutex); boost::mutex::scoped_lock lock(m_statMutex);
if (curNumberOfPlayersOnServer != m_lastStatData.numberOfPlayersOnServer) if (curNumberOfPlayersOnServer != m_statData.numberOfPlayersOnServer)
m_lastStatData.numberOfPlayersOnServer = statData.stats.numberOfPlayersOnServer = curNumberOfPlayersOnServer; {
if (m_totalPlayersLoggedIn != m_lastStatData.totalPlayersEverLoggedIn) m_statData.numberOfPlayersOnServer = stats.numberOfPlayersOnServer = curNumberOfPlayersOnServer;
m_lastStatData.totalPlayersEverLoggedIn = statData.stats.totalPlayersEverLoggedIn = m_totalPlayersLoggedIn; if (curNumberOfPlayersOnServer > m_statData.maxPlayersLoggedIn)
if (m_totalGamesStarted != m_lastStatData.totalGamesEverStarted) m_statData.maxPlayersLoggedIn = curNumberOfPlayersOnServer;
m_lastStatData.totalGamesEverStarted = statData.stats.totalGamesEverStarted = m_totalGamesStarted; m_statDataChanged = true;
}
} }
// Do not send other stats than number of players for now.
BroadcastStatisticsUpdate(stats);
}
if (curNumberOfPlayersOnServer) void
ServerLobbyThread::BroadcastStatisticsUpdate(const ServerStats &stats)
{
if (stats.numberOfPlayersOnServer)
{ {
boost::shared_ptr<NetPacket> packet(new NetPacketStatisticsChanged);
NetPacketStatisticsChanged::Data statData;
statData.stats = stats;
try { try {
static_cast<NetPacketStatisticsChanged *>(packet.get())->SetData(statData); static_cast<NetPacketStatisticsChanged *>(packet.get())->SetData(statData);
@@ -921,6 +954,58 @@ ServerLobbyThread::BroadcastStatisticsUpdate()
} }
} }
void
ServerLobbyThread::ReadStatisticsFile()
{
ifstream i(m_statisticsFileName.c_str(), ios_base::in);
if (!i.fail() && !i.eof())
{
boost::mutex::scoped_lock lock(m_statMutex);
do
{
string statisticsType;
unsigned statisticsValue;
i >> statisticsType;
i >> statisticsValue;
if (statisticsType == SERVER_STATISTICS_STR_TOTAL_PLAYERS)
m_statData.totalPlayersEverLoggedIn = statisticsValue;
else if (statisticsType == SERVER_STATISTICS_STR_TOTAL_GAMES)
m_statData.totalGamesEverStarted = statisticsValue;
else if (statisticsType == SERVER_STATISTICS_STR_MAX_PLAYERS)
m_statData.maxPlayersLoggedIn = statisticsValue;
else if (statisticsType == SERVER_STATISTICS_STR_MAX_GAMES)
m_statData.maxGamesRunning = statisticsValue;
} while (!i.fail() && !i.eof());
m_statDataChanged = false;
}
}
void
ServerLobbyThread::SaveStatisticsFile()
{
if (m_saveStatisticsTimer.elapsed().total_seconds() > SERVER_SAVE_STATISTICS_INTERVAL_SEC)
{
{
boost::mutex::scoped_lock lock(m_statMutex);
if (m_statDataChanged)
{
ofstream o(m_statisticsFileName.c_str(), ios_base::out | ios_base::trunc);
if (!o.fail())
{
o << SERVER_STATISTICS_STR_TOTAL_PLAYERS " " << m_statData.totalPlayersEverLoggedIn << endl;
o << SERVER_STATISTICS_STR_TOTAL_GAMES " " << m_statData.totalGamesEverStarted << endl;
o << SERVER_STATISTICS_STR_MAX_PLAYERS " " << m_statData.maxPlayersLoggedIn << endl;
o << SERVER_STATISTICS_STR_MAX_GAMES " " << m_statData.maxGamesRunning << endl;
m_statDataChanged = false;
}
}
}
m_saveStatisticsTimer.reset();
m_saveStatisticsTimer.start();
}
}
ServerCallback & ServerCallback &
ServerLobbyThread::GetCallback() ServerLobbyThread::GetCallback()
{ {
+1 -1
View File
@@ -42,7 +42,7 @@ public:
virtual ~ServerAcceptThread(); virtual ~ServerAcceptThread();
// Set the parameters. // Set the parameters.
void Init(unsigned serverPort, bool ipv6, bool sctp, const std::string &pwd); void Init(unsigned serverPort, bool ipv6, bool sctp, const std::string &pwd, const std::string &logDir);
ServerCallback &GetCallback(); ServerCallback &GetCallback();
GuiInterface &GetGui(); GuiInterface &GetGui();
+10 -5
View File
@@ -49,7 +49,7 @@ public:
ServerLobbyThread(GuiInterface &gui, ConfigFile *playerConfig, AvatarManager &avatarManager); ServerLobbyThread(GuiInterface &gui, ConfigFile *playerConfig, AvatarManager &avatarManager);
virtual ~ServerLobbyThread(); virtual ~ServerLobbyThread();
void Init(const std::string &pwd); void Init(const std::string &pwd, const std::string &logDir);
void AddConnection(boost::shared_ptr<ConnectData> data); void AddConnection(boost::shared_ptr<ConnectData> data);
void ReAddSession(SessionWrapper session, int reason); void ReAddSession(SessionWrapper session, int reason);
@@ -123,7 +123,11 @@ protected:
void SendError(boost::shared_ptr<SessionData> s, int errorCode); void SendError(boost::shared_ptr<SessionData> s, int errorCode);
void SendJoinGameFailed(boost::shared_ptr<SessionData> s, int reason); void SendJoinGameFailed(boost::shared_ptr<SessionData> s, int reason);
void SendGameList(boost::shared_ptr<SessionData> s); void SendGameList(boost::shared_ptr<SessionData> s);
void BroadcastStatisticsUpdate(); void UpdateStatisticsNumberOfPlayers();
void BroadcastStatisticsUpdate(const ServerStats &stats);
void ReadStatisticsFile();
void SaveStatisticsFile();
SenderThread &GetSender(); SenderThread &GetSender();
ReceiverHelper &GetReceiver(); ReceiverHelper &GetReceiver();
@@ -167,6 +171,7 @@ private:
AvatarManager &m_avatarManager; AvatarManager &m_avatarManager;
std::string m_password; std::string m_password;
std::string m_statisticsFileName;
ConfigFile *m_playerConfig; ConfigFile *m_playerConfig;
u_int32_t m_curGameId; u_int32_t m_curGameId;
@@ -175,12 +180,12 @@ private:
mutable boost::mutex m_curUniquePlayerIdMutex; mutable boost::mutex m_curUniquePlayerIdMutex;
ServerStats m_lastStatData; ServerStats m_statData;
unsigned m_totalPlayersLoggedIn; bool m_statDataChanged;
unsigned m_totalGamesStarted;
mutable boost::mutex m_statMutex; mutable boost::mutex m_statMutex;
boost::timers::portable::microsec_timer m_cacheCleanupTimer; boost::timers::portable::microsec_timer m_cacheCleanupTimer;
boost::timers::portable::microsec_timer m_saveStatisticsTimer;
}; };
#endif #endif
+2 -1
View File
@@ -261,7 +261,8 @@ void Session::startNetworkServer()
myConfig->readConfigInt("ServerPort"), myConfig->readConfigInt("ServerPort"),
myConfig->readConfigInt("ServerUseIpv6") == 1, myConfig->readConfigInt("ServerUseIpv6") == 1,
myConfig->readConfigInt("ServerUseSctp") == 1, myConfig->readConfigInt("ServerUseSctp") == 1,
myConfig->readConfigString("ServerPassword")); myConfig->readConfigString("ServerPassword"),
myConfig->readConfigString("LogDir"));
myNetServer->Run(); myNetServer->Run();
} }