--- /dev/null
+import os
+
+from twisted.web import resource
+
+try:
+ import rrdtool
+except ImportError:
+ class Resource(resource.Resource):
+ def __init__(self):
+ resource.Resource.__init__(self)
+
+ self.putChild('', self)
+
+ def render_GET(self, request):
+ if not request.path.endswith('/'):
+ request.redirect(request.path + '/')
+ return ''
+ request.setHeader('Content-Type', 'text/html')
+ return '<html><head><title>P2Pool Graphs</title></head><body><p>Install python-rrdtool!</p></body></html>'
+
+ class Grapher(object):
+ def __init__(self, *args): pass
+ def add_point(self, *args): pass
+ def get_resource(self): return Resource()
+else:
+ class Renderer(resource.Resource):
+ def __init__(self, path):
+ self.path = path
+ def render_GET(self, request):
+ request.setHeader('Content-Type', 'image/png')
+ rrdtool.graph(self.path + '.png', '--imgformat', 'PNG',
+ '--lower-limit', '0',
+ 'DEF:A=%s:poolrate:AVERAGE' % (self.path,),
+ 'LINE1:A#0000FF:Pool hash rate',
+ )
+ return open(self.path + '.png', 'rb').read()
+
+ class Resource(resource.Resource):
+ def __init__(self, grapher):
+ resource.Resource.__init__(self)
+ self.grapher = grapher
+
+ self.putChild('', self)
+ self.putChild('poolrate', Renderer(self.grapher.path + '.poolrate'))
+
+ def render_GET(self, request):
+ if not request.path.endswith('/'):
+ request.redirect(request.path + '/')
+ return ''
+ request.setHeader('Content-Type', 'text/html')
+ return '<html><head><title>P2Pool Graphs</title></head><body><h1>P2Pool Graphs</h1><h2>Pool hash rate:</h2><img src="poolrate"/></body></html>'
+
+ class Grapher(object):
+ def __init__(self, path):
+ self.path = path
+
+ if not os.path.exists(self.path + '.poolrate'):
+ rrdtool.create(self.path + '.poolrate', '--step', '300', '--no-overwrite',
+ 'DS:poolrate:GAUGE:600:U:U',
+ 'RRA:AVERAGE:0.5:1:288', # last day
+ 'RRA:AVERAGE:0.5:7:288', # last week
+ 'RRA:AVERAGE:0.5:30:288', # last month
+ )
+
+ def add_point(self, poolrate):
+ rrdtool.update(self.path + '.poolrate', '-t', 'poolrate', 'N:%f' % (poolrate,))
+
+ def get_resource(self):
+ return Resource(self)
import bitcoin.p2p as bitcoin_p2p, bitcoin.getwork as bitcoin_getwork, bitcoin.data as bitcoin_data
from bitcoin import worker_interface
from util import expiring_dict, jsonrpc, variable, deferral, math
-from . import p2p, skiplists, networks
+from . import p2p, skiplists, networks, graphs
import p2pool, p2pool.data as p2pool_data
@deferral.retry('Error getting work from bitcoind:', 3)
if draw is not None:
web_root.putChild('chain_img', WebInterface(lambda: draw.get(tracker, current_work.value['best_share_hash']), 'image/png'))
+ grapher = graphs.Grapher(os.path.join(datadir_path, 'rrd'))
+ web_root.putChild('graphs', grapher.get_resource())
+ def add_point():
+ if tracker.get_height(current_work.value['best_share_hash']) < 720:
+ return
+ grapher.add_point(p2pool_data.get_pool_attempts_per_second(tracker, current_work.value['best_share_hash'], 720)
+ / (1 - p2pool_data.get_average_stale_prop(tracker, current_work.value['best_share_hash'], 720)))
+ task.LoopingCall(add_point).start(100)
+
reactor.listenTCP(args.worker_port, server.Site(web_root))
print ' ...success!'