mirror of
https://github.com/evennia/evennia.git
synced 2026-03-17 05:16:31 +01:00
101 lines
3.5 KiB
Python
101 lines
3.5 KiB
Python
"""
|
|
Script that saves memory and idmapper data over time.
|
|
|
|
Data will be saved to game/logs/memoryusage.log. Note that
|
|
the script will append to this file if it already exists.
|
|
|
|
Call this module directly to plot the log (requires matplotlib and numpy).
|
|
"""
|
|
import os, sys
|
|
import time
|
|
#TODO!
|
|
#sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
|
#os.environ['DJANGO_SETTINGS_MODULE'] = 'game.settings'
|
|
import ev
|
|
from evennia.utils.idmapper import base as _idmapper
|
|
|
|
LOGFILE = "logs/memoryusage.log"
|
|
INTERVAL = 30 # log every 30 seconds
|
|
|
|
class Memplot(ev.Script):
|
|
def at_script_creation(self):
|
|
self.key = "memplot"
|
|
self.desc = "Save server memory stats to file"
|
|
self.start_delay = False
|
|
self.persistent = True
|
|
self.interval = INTERVAL
|
|
self.db.starttime = time.time()
|
|
|
|
def at_repeat(self):
|
|
|
|
pid = os.getpid()
|
|
rmem = float(os.popen('ps -p %d -o %s | tail -1' % (pid, "rss")).read()) / 1000.0 # resident memory
|
|
vmem = float(os.popen('ps -p %d -o %s | tail -1' % (pid, "vsz")).read()) / 1000.0 # virtual memory
|
|
total_num, cachedict = _idmapper.cache_size()
|
|
t0 = (time.time() - self.db.starttime) / 60.0 # save in minutes
|
|
|
|
with open(LOGFILE, "a") as f:
|
|
f.write("%s, %s, %s, %s\n" % (t0, rmem, vmem, int(total_num)))
|
|
|
|
if __name__ == "__main__":
|
|
|
|
# plot output from the file
|
|
|
|
from matplotlib import pyplot as pp
|
|
import numpy
|
|
|
|
data = numpy.genfromtxt("../../../game/" + LOGFILE, delimiter=",")
|
|
secs = data[:,0]
|
|
rmem = data[:,1]
|
|
vmem = data[:,2]
|
|
nobj = data[:,3]
|
|
|
|
# calculate derivative of obj creation
|
|
#oderiv = (0.5*(nobj[2:] - nobj[:-2]) / (secs[2:] - secs[:-2])).copy()
|
|
#oderiv = (0.5*(rmem[2:] - rmem[:-2]) / (secs[2:] - secs[:-2])).copy()
|
|
|
|
fig = pp.figure()
|
|
ax1 = fig.add_subplot(111)
|
|
ax1.set_title("1000 bots (normal players with light building)")
|
|
ax1.set_xlabel("Time (mins)")
|
|
ax1.set_ylabel("Memory usage (MB)")
|
|
ax1.plot(secs, rmem, "r", label="RMEM", lw=2)
|
|
ax1.plot(secs, vmem, "b", label="VMEM", lw=2)
|
|
ax1.legend(loc="upper left")
|
|
|
|
ax2 = ax1.twinx()
|
|
ax2.plot(secs, nobj, "g--", label="objs in cache", lw=2)
|
|
#ax2.plot(secs[:-2], oderiv/60.0, "g--", label="Objs/second", lw=2)
|
|
#ax2.plot(secs[:-2], oderiv, "g--", label="Objs/second", lw=2)
|
|
ax2.set_ylabel("Number of objects")
|
|
ax2.legend(loc="lower right")
|
|
ax2.annotate("First 500 bots\nconnecting", xy=(10, 4000))
|
|
ax2.annotate("Next 500 bots\nconnecting", xy=(350,10000))
|
|
#ax2.annotate("@reload", xy=(185,600))
|
|
|
|
# # plot mem vs cachesize
|
|
# nobj, rmem, vmem = nobj[:262].copy(), rmem[:262].copy(), vmem[:262].copy()
|
|
#
|
|
# fig = pp.figure()
|
|
# ax1 = fig.add_subplot(111)
|
|
# ax1.set_title("Memory usage per cache size")
|
|
# ax1.set_xlabel("Cache size (number of objects)")
|
|
# ax1.set_ylabel("Memory usage (MB)")
|
|
# ax1.plot(nobj, rmem, "r", label="RMEM", lw=2)
|
|
# ax1.plot(nobj, vmem, "b", label="VMEM", lw=2)
|
|
#
|
|
|
|
## # empirical estimate of memory usage: rmem = 35.0 + 0.0157 * Ncache
|
|
## # Ncache = int((rmem - 35.0) / 0.0157) (rmem in MB)
|
|
#
|
|
# rderiv_aver = 0.0157
|
|
# fig = pp.figure()
|
|
# ax1 = fig.add_subplot(111)
|
|
# ax1.set_title("Relation between memory and cache size")
|
|
# ax1.set_xlabel("Memory usage (MB)")
|
|
# ax1.set_ylabel("Idmapper Cache Size (number of objects)")
|
|
# rmem = numpy.linspace(35, 2000, 2000)
|
|
# nobjs = numpy.array([int((mem - 35.0) / 0.0157) for mem in rmem])
|
|
# ax1.plot(rmem, nobjs, "r", lw=2)
|
|
|
|
pp.show()
|