feat(Core/Metrics): implement real time statistic visualization (#8663)

This commit is contained in:
Kargatum
2021-10-28 19:47:29 +07:00
committed by GitHub
parent 7c363c9040
commit a650fd495c
21 changed files with 4798 additions and 31 deletions

View File

@@ -60,6 +60,7 @@
#include "LootMgr.h"
#include "MMapFactory.h"
#include "MapMgr.h"
#include "Metric.h"
#include "ObjectMgr.h"
#include "Opcodes.h"
#include "OutdoorPvPMgr.h"
@@ -437,6 +438,7 @@ void World::LoadConfigSettings(bool reload)
}
sLog->LoadFromConfig();
sMetric->LoadFromConfigs();
}
// Set realm id and enable db logging
@@ -2107,10 +2109,13 @@ void World::SetInitialWorldSettings()
}
uint32 startupDuration = GetMSTimeDiffToNow(startupBegin);
LOG_INFO("server.loading", " ");
LOG_INFO("server.loading", "WORLD: World initialized in %u minutes %u seconds", (startupDuration / 60000), ((startupDuration % 60000) / 1000)); // outError for red color in console
LOG_INFO("server.loading", " ");
METRIC_EVENT("events", "World initialized", "World initialized in " + std::to_string(startupDuration / 60000) + " minutes " + std::to_string((startupDuration % 60000) / 1000) + " seconds");
if (sConfigMgr->isDryRun())
{
LOG_INFO("server.loading", "AzerothCore dry run completed, terminating.");
@@ -2199,6 +2204,8 @@ void World::LoadAutobroadcasts()
/// Update the World !
void World::Update(uint32 diff)
{
METRIC_TIMER("world_update_time_total");
m_updateTime = diff;
if (m_int_configs[CONFIG_INTERVAL_LOG_UPDATE])
@@ -2238,26 +2245,45 @@ void World::Update(uint32 diff)
///- Update the game time and check for shutdown time
_UpdateGameTime();
/// Handle daily quests reset time
if (m_gameTime > m_NextDailyQuestReset)
ResetDailyQuests();
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Check quest reset times"));
/// Handle weekly quests reset time
if (m_gameTime > m_NextWeeklyQuestReset)
ResetWeeklyQuests();
/// Handle daily quests reset time
if (m_gameTime > m_NextDailyQuestReset)
{
ResetDailyQuests();
}
/// Handle monthly quests reset time
if (m_gameTime > m_NextMonthlyQuestReset)
ResetMonthlyQuests();
/// Handle weekly quests reset time
if (m_gameTime > m_NextWeeklyQuestReset)
{
ResetWeeklyQuests();
}
/// Handle monthly quests reset time
if (m_gameTime > m_NextMonthlyQuestReset)
{
ResetMonthlyQuests();
}
}
if (m_gameTime > m_NextRandomBGReset)
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Reset random BG"));
ResetRandomBG();
}
if (m_gameTime > m_NextCalendarOldEventsDeletionTime)
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Delete old calendar events"));
CalendarDeleteOldEvents();
}
if (m_gameTime > m_NextGuildReset)
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Reset guild cap"));
ResetGuildCap();
}
// pussywizard:
// acquire mutex now, this is kind of waiting for listing thread to finish it's work (since it can't process next packet)
@@ -2269,6 +2295,8 @@ void World::Update(uint32 diff)
// pussywizard: handle auctions when the timer has passed
if (m_timers[WUPDATE_AUCTIONS].Passed())
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update expired auctions"));
m_timers[WUPDATE_AUCTIONS].Reset();
// pussywizard: handle expired auctions, auctions expired when realm was offline are also handled here (not during loading when many required things aren't loaded yet)
@@ -2283,8 +2311,13 @@ void World::Update(uint32 diff)
mail_expire_check_timer = m_gameTime + 6 * 3600;
}
UpdateSessions(diff);
{
/// <li> Handle session updates when the timer has passed
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update sessions"));
UpdateSessions(diff);
}
}
// end of section with mutex
AsyncAuctionListingMgr::SetAuctionListingAllowed(true);
@@ -2300,6 +2333,8 @@ void World::Update(uint32 diff)
{
if (m_timers[WUPDATE_CLEANDB].Passed())
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Clean logs table"));
m_timers[WUPDATE_CLEANDB].Reset();
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_OLD_LOGS);
@@ -2311,33 +2346,58 @@ void World::Update(uint32 diff)
}
}
sLFGMgr->Update(diff, 0); // pussywizard: remove obsolete stuff before finding compatibility during map update
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update LFG 0"));
sLFGMgr->Update(diff, 0); // pussywizard: remove obsolete stuff before finding compatibility during map update
}
sMapMgr->Update(diff);
///- Update objects when the timer has passed (maps, transport, creatures, ...)
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update maps"));
sMapMgr->Update(diff);
}
if (sWorld->getBoolConfig(CONFIG_AUTOBROADCAST))
{
if (m_timers[WUPDATE_AUTOBROADCAST].Passed())
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Send autobroadcast"));
m_timers[WUPDATE_AUTOBROADCAST].Reset();
SendAutoBroadcast();
}
}
sBattlegroundMgr->Update(diff);
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update battlegrounds"));
sBattlegroundMgr->Update(diff);
}
sOutdoorPvPMgr->Update(diff);
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update outdoor pvp"));
sOutdoorPvPMgr->Update(diff);
}
sBattlefieldMgr->Update(diff);
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update battlefields"));
sBattlefieldMgr->Update(diff);
}
sLFGMgr->Update(diff, 2); // pussywizard: handle created proposals
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update LFG 2"));
sLFGMgr->Update(diff, 2); // pussywizard: handle created proposals
}
// execute callbacks from sql queries that were queued recently
ProcessQueryCallbacks();
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Process query callbacks"));
// execute callbacks from sql queries that were queued recently
ProcessQueryCallbacks();
}
/// <li> Update uptime table
if (m_timers[WUPDATE_UPTIME].Passed())
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update uptime"));
uint32 tmpDiff = uint32(m_gameTime - m_startTime);
uint32 maxOnlinePlayers = GetMaxPlayerCount();
@@ -2356,6 +2416,7 @@ void World::Update(uint32 diff)
///- Erase corpses once every 20 minutes
if (m_timers[WUPDATE_CORPSES].Passed())
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Remove old corpses"));
m_timers[WUPDATE_CORPSES].Reset();
sMapMgr->DoForAllMaps([](Map* map)
{
@@ -2366,6 +2427,7 @@ void World::Update(uint32 diff)
///- Process Game events when necessary
if (m_timers[WUPDATE_EVENTS].Passed())
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update game events"));
m_timers[WUPDATE_EVENTS].Reset(); // to give time for Update() to be processed
uint32 nextGameEvent = sGameEventMgr->Update();
m_timers[WUPDATE_EVENTS].SetInterval(nextGameEvent);
@@ -2375,6 +2437,7 @@ void World::Update(uint32 diff)
///- Ping to keep MySQL connections alive
if (m_timers[WUPDATE_PINGDB].Passed())
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Ping MySQL"));
m_timers[WUPDATE_PINGDB].Reset();
LOG_DEBUG("sql.driver", "Ping MySQL to keep connection alive");
CharacterDatabase.KeepAlive();
@@ -2382,15 +2445,34 @@ void World::Update(uint32 diff)
WorldDatabase.KeepAlive();
}
// update the instance reset times
sInstanceSaveMgr->Update();
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update instance reset times"));
// update the instance reset times
sInstanceSaveMgr->Update();
}
// And last, but not least handle the issued cli commands
ProcessCliCommands();
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Process cli commands"));
// And last, but not least handle the issued cli commands
ProcessCliCommands();
}
sScriptMgr->OnWorldUpdate(diff);
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update world scripts"));
sScriptMgr->OnWorldUpdate(diff);
}
SavingSystemMgr::Update(diff);
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update saving system"));
SavingSystemMgr::Update(diff);
}
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update metrics"));
// Stats logger update
sMetric->Update();
METRIC_VALUE("update_time_diff", diff);
}
}
void World::ForceGameEventUpdate()
@@ -2710,10 +2792,18 @@ void World::SendServerMessage(ServerMessageType type, const char* text, Player*
void World::UpdateSessions(uint32 diff)
{
///- Add new sessions
WorldSession* sess = nullptr;
while (addSessQueue.next(sess))
AddSession_ (sess);
{
METRIC_DETAILED_NO_THRESHOLD_TIMER("world_update_time",
METRIC_TAG("type", "Add sessions"),
METRIC_TAG("parent_type", "Update sessions"));
///- Add new sessions
WorldSession* sess = nullptr;
while (addSessQueue.next(sess))
{
AddSession_(sess);
}
}
///- Then send an update signal to remaining ones
for (SessionMap::iterator itr = m_sessions.begin(), next; itr != m_sessions.end(); itr = next)
@@ -2745,6 +2835,9 @@ void World::UpdateSessions(uint32 diff)
continue;
}
[[maybe_unused]] uint32 currentSessionId = itr->first;
METRIC_DETAILED_TIMER("world_update_sessions_time", METRIC_TAG("account_id", std::to_string(currentSessionId)));
if (!pSession->Update(diff, updater))
{
if (!RemoveQueuedPlayer(pSession) && getIntConfig(CONFIG_INTERVAL_DISCONNECT_TOLERANCE))