Adding some stats for serverinfo
This commit is contained in:
parent
e9dcc88f29
commit
d0af7e4fa9
7 changed files with 235 additions and 64 deletions
|
|
@ -195,6 +195,7 @@ SET(common_headers
|
|||
say_link.h
|
||||
seperator.h
|
||||
serialize_buffer.h
|
||||
server_stats.h
|
||||
serverinfo.h
|
||||
servertalk.h
|
||||
shareddb.h
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "../opcodemgr.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../eqemu_logsys_fmt.h"
|
||||
#include "../server_stats.h"
|
||||
#include "daybreak_connection.h"
|
||||
#include <thread>
|
||||
#include <concurrentqueue.h>
|
||||
|
|
@ -85,20 +86,27 @@ void EQ::Net::ConcurrentEQStreamManager::_BackgroundThread() {
|
|||
_impl->background_update_stats_timer.reset(new EQ::Timer(&loop, 500, true,
|
||||
std::bind(&ConcurrentEQStreamManager::_BackgroundUpdateStatsTimer, this, std::placeholders::_1)));
|
||||
|
||||
int sleep_time = 16;
|
||||
while (true == _impl->background_running) {
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
EQ::ServerStats::Get().BeginNetworkFrame();
|
||||
loop.Process();
|
||||
|
||||
switch (_impl->priority) {
|
||||
case EQStreamPriority::Low:
|
||||
Sleep(10);
|
||||
sleep_time = 200;
|
||||
break;
|
||||
case EQStreamPriority::Normal:
|
||||
Sleep(5);
|
||||
sleep_time = 100;
|
||||
break;
|
||||
case EQStreamPriority::High:
|
||||
Sleep(1);
|
||||
sleep_time = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
EQ::ServerStats::Get().EndNetworkFrame();
|
||||
auto end = now + std::chrono::milliseconds(sleep_time);
|
||||
std::this_thread::sleep_until(end);
|
||||
}
|
||||
|
||||
_impl->background_loop_timer.release();
|
||||
|
|
|
|||
164
common/server_stats.h
Normal file
164
common/server_stats.h
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <uv.h>
|
||||
|
||||
namespace EQ
|
||||
{
|
||||
struct ResourceUsageStats
|
||||
{
|
||||
double user_cpu_time;
|
||||
double system_cpu_time;
|
||||
};
|
||||
|
||||
struct OSInfoStats
|
||||
{
|
||||
std::string system_name;
|
||||
std::string release;
|
||||
std::string version;
|
||||
std::string machine;
|
||||
};
|
||||
|
||||
class ServerStats
|
||||
{
|
||||
typedef std::chrono::high_resolution_clock clock;
|
||||
typedef std::chrono::high_resolution_clock::time_point timestamp;
|
||||
typedef std::chrono::duration<double> seconds;
|
||||
public:
|
||||
~ServerStats() {
|
||||
}
|
||||
|
||||
static ServerStats& Get() {
|
||||
static ServerStats inst;
|
||||
return inst;
|
||||
}
|
||||
|
||||
void BeginFrame()
|
||||
{
|
||||
auto now = clock::now();
|
||||
auto inactive = now - m_last_end;
|
||||
m_inactive_time = std::chrono::duration_cast<seconds>(inactive).count();
|
||||
m_last_begin = now;
|
||||
}
|
||||
|
||||
void EndFrame() {
|
||||
auto now = clock::now();
|
||||
auto active = now - m_last_begin;
|
||||
m_active_time = std::chrono::duration_cast<seconds>(active).count();
|
||||
m_last_end = now;
|
||||
}
|
||||
|
||||
double InactiveFrameTime() const {
|
||||
return m_inactive_time;
|
||||
}
|
||||
|
||||
double ActiveFrameTime() const {
|
||||
return m_active_time;
|
||||
}
|
||||
|
||||
double FrameTime() const {
|
||||
return m_inactive_time + m_active_time;
|
||||
}
|
||||
|
||||
void BeginNetworkFrame()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_network_lock);
|
||||
auto now = clock::now();
|
||||
auto inactive = now - m_network_last_end;
|
||||
m_network_inactive_time = std::chrono::duration_cast<seconds>(inactive).count();
|
||||
m_network_last_begin = now;
|
||||
}
|
||||
|
||||
void EndNetworkFrame()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_network_lock);
|
||||
auto now = clock::now();
|
||||
auto active = now - m_network_last_begin;
|
||||
m_network_active_time = std::chrono::duration_cast<seconds>(active).count();
|
||||
m_network_last_end = now;
|
||||
}
|
||||
|
||||
double NetworkInactiveFrameTime() {
|
||||
std::lock_guard<std::mutex> lock(m_network_lock);
|
||||
return m_network_inactive_time;
|
||||
}
|
||||
|
||||
double NetworkActiveFrameTime() {
|
||||
std::lock_guard<std::mutex> lock(m_network_lock);
|
||||
return m_network_active_time;
|
||||
}
|
||||
|
||||
double NetworkFrameTime() {
|
||||
std::lock_guard<std::mutex> lock(m_network_lock);
|
||||
return m_network_inactive_time + m_network_active_time;
|
||||
}
|
||||
|
||||
//OS Related Stuff
|
||||
int PID() {
|
||||
return uv_os_getpid();
|
||||
}
|
||||
|
||||
int ParentPID() {
|
||||
return uv_os_getppid();
|
||||
}
|
||||
|
||||
ResourceUsageStats ResourceUsage() {
|
||||
uv_rusage_t usage;
|
||||
if(0 != uv_getrusage(&usage)) {
|
||||
return ResourceUsageStats();
|
||||
}
|
||||
|
||||
ResourceUsageStats ret;
|
||||
ret.user_cpu_time = static_cast<double>(usage.ru_utime.tv_sec) + static_cast<double>(usage.ru_utime.tv_usec / 1000000.0);
|
||||
ret.system_cpu_time = static_cast<double>(usage.ru_stime.tv_sec) + static_cast<double>(usage.ru_stime.tv_usec / 1000000.0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
OSInfoStats OSInfo() {
|
||||
uv_utsname_t osn;
|
||||
|
||||
if (0 != uv_os_uname(&osn)) {
|
||||
return OSInfoStats();
|
||||
}
|
||||
|
||||
OSInfoStats ret;
|
||||
ret.system_name = osn.sysname;
|
||||
ret.release = osn.release;
|
||||
ret.version = osn.version;
|
||||
ret.machine = osn.machine;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//Compile related things
|
||||
bool IsDebug() {
|
||||
#ifdef NDEBUG
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
private:
|
||||
ServerStats() {
|
||||
m_last_begin = clock::now();
|
||||
m_last_end = clock::now();
|
||||
m_network_last_begin = clock::now();
|
||||
m_network_last_end = clock::now();
|
||||
}
|
||||
|
||||
//Main thread
|
||||
timestamp m_last_begin;
|
||||
timestamp m_last_end;
|
||||
double m_inactive_time;
|
||||
double m_active_time;
|
||||
|
||||
//Network thread
|
||||
std::mutex m_network_lock;
|
||||
timestamp m_network_last_begin;
|
||||
timestamp m_network_last_end;
|
||||
double m_network_inactive_time;
|
||||
double m_network_active_time;
|
||||
};
|
||||
}
|
||||
|
|
@ -56,6 +56,7 @@
|
|||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/profanity_manager.h"
|
||||
#include "../common/net/eqstream.h"
|
||||
#include "../common/server_stats.h"
|
||||
|
||||
#include "data_bucket.h"
|
||||
#include "command.h"
|
||||
|
|
@ -351,7 +352,7 @@ int command_init(void)
|
|||
command_add("scribespells", "[max level] [min level] - Scribe all spells for you or your player target that are usable by them, up to level specified. (may freeze client for a few seconds)", 150, command_scribespells) ||
|
||||
command_add("sendzonespawns", "- Refresh spawn list for all clients in zone", 150, command_sendzonespawns) ||
|
||||
command_add("sensetrap", "Analog for ldon sense trap for the newer clients since we still don't have it working.", 0, command_sensetrap) ||
|
||||
command_add("serverinfo", "- Get OS info about server host", 200, command_serverinfo) ||
|
||||
command_add("serverinfo", "- Various info about the current running instance.", 200, command_serverinfo) ||
|
||||
command_add("serverrules", "- Read this server's rules", 0, command_serverrules) ||
|
||||
command_add("setaapts", "[value] - Set your or your player target's available AA points", 100, command_setaapts) ||
|
||||
command_add("setaaxp", "[value] - Set your or your player target's AA experience", 100, command_setaaxp) ||
|
||||
|
|
@ -843,22 +844,6 @@ void command_setanim(Client *c, const Seperator *sep)
|
|||
}
|
||||
}
|
||||
|
||||
void command_serverinfo(Client *c, const Seperator *sep)
|
||||
{
|
||||
#ifdef _WINDOWS
|
||||
char intbuffer [sizeof(unsigned long)];
|
||||
c->Message(0, "Operating system information.");
|
||||
c->Message(0, " %s", Ver_name);
|
||||
c->Message(0, " Build number: %s", ultoa(Ver_build, intbuffer, 10));
|
||||
c->Message(0, " Minor version: %s", ultoa(Ver_min, intbuffer, 10));
|
||||
c->Message(0, " Major version: %s", ultoa(Ver_maj, intbuffer, 10));
|
||||
c->Message(0, " Platform Id: %s", ultoa(Ver_pid, intbuffer, 10));
|
||||
#else
|
||||
char buffer[255];
|
||||
c->Message(0, "Operating system information: %s", GetOS(buffer));
|
||||
#endif
|
||||
}
|
||||
|
||||
void command_getvariable(Client *c, const Seperator *sep)
|
||||
{
|
||||
std::string tmp;
|
||||
|
|
@ -12371,6 +12356,35 @@ void command_network(Client *c, const Seperator *sep)
|
|||
}
|
||||
}
|
||||
|
||||
void command_serverinfo(Client *c, const Seperator *sep)
|
||||
{
|
||||
auto &stats = EQ::ServerStats::Get();
|
||||
auto rusage = stats.ResourceUsage();
|
||||
auto osn = stats.OSInfo();
|
||||
|
||||
c->Message(0, "------------------------------------------------");
|
||||
c->Message(0, "Process");
|
||||
c->Message(0, "------------------------------------------------");
|
||||
c->Message(0, "PID: %u", stats.PID());
|
||||
c->Message(0, "DEBUG: %s", stats.IsDebug() ? "ON" : "OFF");
|
||||
c->Message(0, "%s (%s %s %s)", osn.version.c_str(), osn.system_name.c_str(), osn.release.c_str(), osn.machine.c_str());
|
||||
|
||||
c->Message(0, "------------------------------------------------");
|
||||
c->Message(0, "CPU");
|
||||
c->Message(0, "------------------------------------------------");
|
||||
c->Message(0, "Usage: User %.2f sec, System %.2f sec", rusage.user_cpu_time, rusage.system_cpu_time);
|
||||
c->Message(0, "Frame Time (Main): %.2f ms (active: %.2f ms) (inactive: %.2f ms) (%.2f fps)",
|
||||
stats.FrameTime() * 1000.0,
|
||||
stats.ActiveFrameTime() * 1000.0,
|
||||
stats.InactiveFrameTime() * 1000.0,
|
||||
1.0 / stats.FrameTime());
|
||||
c->Message(0, "Frame Time (Network): %.2f ms (active: %.2f ms) (inactive: %.2f ms) (%.2f fps)",
|
||||
stats.NetworkFrameTime() * 1000.0,
|
||||
stats.NetworkActiveFrameTime() * 1000.0,
|
||||
stats.NetworkInactiveFrameTime() * 1000.0,
|
||||
1.0 / stats.NetworkFrameTime());
|
||||
}
|
||||
|
||||
// All new code added to command.cpp should be BEFORE this comment line. Do no append code to this file below the BOTS code block.
|
||||
#ifdef BOTS
|
||||
#include "bot_command.h"
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@
|
|||
#include "../common/eq_packet_structs.h"
|
||||
#include "../common/misc_functions.h"
|
||||
#include "../common/data_verification.h"
|
||||
#include "../common/server_stats.h"
|
||||
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern double frame_time;
|
||||
extern Zone *zone;
|
||||
|
||||
class IMovementCommand
|
||||
|
|
@ -69,7 +69,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
auto td = rotate_to_speed * 19.0 * frame_time;
|
||||
auto td = rotate_to_speed * 19.0 * EQ::ServerStats::Get().FrameTime();
|
||||
|
||||
if (td >= dist) {
|
||||
m->SetHeading(to);
|
||||
|
|
@ -186,7 +186,7 @@ public:
|
|||
|
||||
glm::vec2 dir = tar - pos;
|
||||
glm::vec2 ndir = glm::normalize(dir);
|
||||
double distance_moved = frame_time * current_speed * 0.4f * 1.45f;
|
||||
double distance_moved = EQ::ServerStats::Get().FrameTime() * current_speed * 0.4f * 1.45f;
|
||||
|
||||
if (distance_moved > len) {
|
||||
if (m->IsNPC()) {
|
||||
|
|
@ -313,7 +313,7 @@ public:
|
|||
|
||||
glm::vec2 dir = tar - pos;
|
||||
glm::vec2 ndir = glm::normalize(dir);
|
||||
double distance_moved = frame_time * current_speed * 0.4f * 1.45f;
|
||||
double distance_moved = EQ::ServerStats::Get().FrameTime() * current_speed * 0.4f * 1.45f;
|
||||
|
||||
if (distance_moved > len) {
|
||||
if (m->IsNPC()) {
|
||||
|
|
|
|||
59
zone/net.cpp
59
zone/net.cpp
|
|
@ -71,6 +71,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "../common/event/timer.h"
|
||||
#include "../common/net/eqstream.h"
|
||||
#include "../common/net/servertalk_server.h"
|
||||
#include "../common/server_stats.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
|
@ -118,7 +119,6 @@ EQEmuLogSys LogSys;
|
|||
const SPDat_Spell_Struct* spells;
|
||||
int32 SPDAT_RECORDS = -1;
|
||||
const ZoneConfig *Config;
|
||||
double frame_time = 0.0;
|
||||
|
||||
void Shutdown();
|
||||
extern void MapOpcodes();
|
||||
|
|
@ -466,16 +466,24 @@ int main(int argc, char** argv) {
|
|||
std::chrono::time_point<std::chrono::system_clock> frame_prev = std::chrono::system_clock::now();
|
||||
std::unique_ptr<EQ::Net::ConsoleServer> console;
|
||||
|
||||
auto loop_fn = [&](EQ::Timer* t) {
|
||||
//Advance the timer to our current point in time
|
||||
Timer::SetCurrentTime();
|
||||
int sleep_time = 16;
|
||||
while (RunLoops) {
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
|
||||
/**
|
||||
* Calculate frame time
|
||||
*/
|
||||
std::chrono::time_point<std::chrono::system_clock> frame_now = std::chrono::system_clock::now();
|
||||
frame_time = std::chrono::duration_cast<std::chrono::duration<double>>(frame_now - frame_prev).count();
|
||||
frame_prev = frame_now;
|
||||
EQ::ServerStats::Get().BeginFrame();
|
||||
bool previous_loaded = is_zone_loaded && numclients > 0;
|
||||
Timer::SetCurrentTime();
|
||||
EQ::EventLoop::GetDefault().Process();
|
||||
bool current_loaded = is_zone_loaded && numclients > 0;
|
||||
|
||||
if (previous_loaded && !current_loaded) {
|
||||
sleep_time = 100;
|
||||
eqsm->SetPriority(EQStreamPriority::Low);
|
||||
}
|
||||
else if (!previous_loaded && current_loaded) {
|
||||
sleep_time = 16;
|
||||
eqsm->SetPriority(EQStreamPriority::High);
|
||||
}
|
||||
|
||||
/**
|
||||
* Telnet server
|
||||
|
|
@ -512,7 +520,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
eqsm->OnNewConnection([&stream_identifier](std::shared_ptr<EQStreamInterface> stream) {
|
||||
stream_identifier.AddStream(stream);
|
||||
LogF(Logs::Detail, Logs::World_Server, "New connection from IP {0}:{1}", stream->GetRemoteIP(), ntohs(stream->GetRemotePort()));
|
||||
LogF(Logs::Detail, Logs::World_Server, "New connection from IP {0}:{1}", stream->GetRemoteAddr(), ntohs(stream->GetRemotePort()));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -581,33 +589,10 @@ int main(int argc, char** argv) {
|
|||
database.ping();
|
||||
entity_list.UpdateWho();
|
||||
}
|
||||
};
|
||||
|
||||
EQ::Timer process_timer(loop_fn);
|
||||
process_timer.Start(1000, true);
|
||||
|
||||
while (RunLoops) {
|
||||
bool previous_loaded = is_zone_loaded && numclients > 0;
|
||||
EQ::EventLoop::GetDefault().Process();
|
||||
|
||||
bool current_loaded = is_zone_loaded && numclients > 0;
|
||||
if (previous_loaded && !current_loaded) {
|
||||
process_timer.Stop();
|
||||
process_timer.Start(1000, true);
|
||||
eqsm->SetPriority(EQStreamPriority::Low);
|
||||
}
|
||||
else if (!previous_loaded && current_loaded) {
|
||||
process_timer.Stop();
|
||||
process_timer.Start(32, true);
|
||||
eqsm->SetPriority(EQStreamPriority::High);
|
||||
}
|
||||
|
||||
if (current_loaded) {
|
||||
Sleep(1);
|
||||
}
|
||||
else {
|
||||
Sleep(10);
|
||||
}
|
||||
EQ::ServerStats::Get().EndFrame();
|
||||
auto end = now + std::chrono::milliseconds(sleep_time);
|
||||
std::this_thread::sleep_until(end);
|
||||
}
|
||||
|
||||
entity_list.Clear();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/server_stats.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "entity.h"
|
||||
|
|
@ -27,8 +28,6 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
extern double frame_time;
|
||||
|
||||
int Mob::GetBaseSkillDamage(EQEmu::skills::SkillType skill, Mob *target)
|
||||
{
|
||||
int base = EQEmu::skills::GetBaseDamage(skill);
|
||||
|
|
@ -1033,7 +1032,7 @@ void Mob::ProjectileAttack()
|
|||
ProjectileAtk[i].skill = 0;
|
||||
ProjectileAtk[i].speed_mod = 0.0f;
|
||||
} else {
|
||||
ProjectileAtk[i].increment += 1000 * frame_time;
|
||||
ProjectileAtk[i].increment += 1000 * EQ::ServerStats::Get().FrameTime();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue