stats: Dump a JSON file next to the pickle file.

Extremely useful for interoperating with non-Python (e.g. Monte) tooling.
This commit is contained in:
Corbin Simpson 2016-02-26 11:14:31 -08:00 committed by Brian Warner
parent e187fba58e
commit e1dba4abeb
2 changed files with 19 additions and 5 deletions

View File

@ -310,13 +310,14 @@ given port. The portnum file is actually a "strports specification string",
as described in :doc:`configuration`. as described in :doc:`configuration`.
Once running, the stats gatherer will create a standard python "pickle" file Once running, the stats gatherer will create a standard python "pickle" file
in $BASEDIR/stats.pickle . Once a minute, the gatherer will pull stats in ``$BASEDIR/stats.pickle``, and a standard JSON file in
``$BASEDIR/stats.json``. Once a minute, the gatherer will pull stats
information from every connected node and write them into the pickle. The information from every connected node and write them into the pickle. The
pickle will contain a dictionary, in which node identifiers (known as "tubid" pickle will contain a dictionary, in which node identifiers (known as "tubid"
strings) are the keys, and the values are a dict with 'timestamp', strings) are the keys, and the values are a dict with 'timestamp', 'nickname',
'nickname', and 'stats' keys. d[tubid][stats] will contain the stats and 'stats' keys. d[tubid][stats] will contain the stats dictionary as made
dictionary as made available at http://localhost:3456/statistics?t=json . The available at http://localhost:3456/statistics?t=json . The pickle file will
pickle file will only contain the most recent update from each node. only contain the most recent update from each node.
Other tools can be built to examine these stats and render them into Other tools can be built to examine these stats and render them into
something useful. For example, a tool could sum the something useful. For example, a tool could sum the

View File

@ -1,4 +1,5 @@
import json
import os import os
import pickle import pickle
import pprint import pprint
@ -247,6 +248,7 @@ class PickleStatsGatherer(StdOutStatsGatherer):
self.verbose = verbose self.verbose = verbose
StatsGatherer.__init__(self, basedir) StatsGatherer.__init__(self, basedir)
self.picklefile = os.path.join(basedir, "stats.pickle") self.picklefile = os.path.join(basedir, "stats.pickle")
self.jsonfile = os.path.join(basedir, "stats.json")
if os.path.exists(self.picklefile): if os.path.exists(self.picklefile):
f = open(self.picklefile, 'rb') f = open(self.picklefile, 'rb')
@ -267,6 +269,7 @@ class PickleStatsGatherer(StdOutStatsGatherer):
s['nickname'] = nickname s['nickname'] = nickname
s['stats'] = stats s['stats'] = stats
self.dump_pickle() self.dump_pickle()
self.dump_json()
def dump_pickle(self): def dump_pickle(self):
tmp = "%s.tmp" % (self.picklefile,) tmp = "%s.tmp" % (self.picklefile,)
@ -277,6 +280,16 @@ class PickleStatsGatherer(StdOutStatsGatherer):
os.unlink(self.picklefile) os.unlink(self.picklefile)
os.rename(tmp, self.picklefile) os.rename(tmp, self.picklefile)
def dump_json(self):
# Same logic as pickle, but using JSON instead.
tmp = "%s.tmp" % (self.jsonfile,)
f = open(tmp, 'wb')
json.dump(self.gathered_stats, f)
f.close()
if os.path.exists(self.jsonfile):
os.unlink(self.jsonfile)
os.rename(tmp, self.jsonfile)
class StatsGathererService(service.MultiService): class StatsGathererService(service.MultiService):
furl_file = "stats_gatherer.furl" furl_file = "stats_gatherer.furl"