X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=apt_p2p_Khashmir%2Fstats.py;h=5afc17ab077112c2c9748eadfe17d698dc0eba43;hb=ce20dde0bf4440dbb651bae51f85750aa8afdb8e;hp=e2752dd379223707730c3517f3224ec2ac77a018;hpb=80f92d033a70cb932d76768e96c681475031d7b7;p=quix0rs-apt-p2p.git
diff --git a/apt_p2p_Khashmir/stats.py b/apt_p2p_Khashmir/stats.py
index e2752dd..5afc17a 100644
--- a/apt_p2p_Khashmir/stats.py
+++ b/apt_p2p_Khashmir/stats.py
@@ -2,12 +2,11 @@
"""Store statistics for the Khashmir DHT."""
from datetime import datetime, timedelta
-from copy import deepcopy
+from StringIO import StringIO
class StatsLogger:
"""Store the statistics for the Khashmir DHT.
- @ivar _StatsTemplate: a template for returning all the statistics
@type config: C{dictionary}
@ivar config: the configuration parameters for the DHT
@ivar startTime: the time the program was started
@@ -32,86 +31,6 @@ class StatsLogger:
generated an error
"""
- _StatsTemplate = [{'name': 'uptime',
- 'group': 'General',
- 'desc': 'Up time',
- 'tip': 'The elapsed time since the program started',
- 'value': None,
- },
- {'name': 'reachable',
- 'group': 'General',
- 'desc': 'Reachable',
- 'tip': 'Whether other nodes can contact us (not NATted or firewalled)',
- 'value': None,
- },
- {'name': 'nodes',
- 'group': 'Routing Table',
- 'desc': 'Number of nodes',
- 'tip': 'The number of nodes we are connected to',
- 'value': None,
- },
- {'name': 'users',
- 'group': 'Routing Table',
- 'desc': 'Total number of users',
- 'tip': 'The estimated total number of users in the DHT',
- 'value': None,
- },
- {'name': 'keys',
- 'group': 'Database',
- 'desc': 'Keys',
- 'tip': 'The number of distinct keys in the database',
- 'value': None,
- },
- {'name': 'values',
- 'group': 'Database',
- 'desc': 'Values',
- 'tip': 'The total number of values in the database',
- 'value': None,
- },
- {'name': 'downPackets',
- 'group': 'Transport',
- 'desc': 'Downloaded packets',
- 'tip': 'The number of received packets',
- 'value': None,
- },
- {'name': 'upPackets',
- 'group': 'Transport',
- 'desc': 'Uploaded packets',
- 'tip': 'The number of sent packets',
- 'value': None,
- },
- {'name': 'downBytes',
- 'group': 'Transport',
- 'desc': 'Downloaded bytes',
- 'tip': 'The number of bytes received by the DHT',
- 'value': None,
- },
- {'name': 'upBytes',
- 'group': 'Transport',
- 'desc': 'Uploaded bytes',
- 'tip': 'The number of bytes sent by the DHT',
- 'value': None,
- },
- {'name': 'downSpeed',
- 'group': 'Transport',
- 'desc': 'Downloaded bytes/second',
- 'tip': 'The number of bytes received by the DHT per second',
- 'value': None,
- },
- {'name': 'upSpeed',
- 'group': 'Transport',
- 'desc': 'Uploaded bytes/second',
- 'tip': 'The number of bytes sent by the DHT per second',
- 'value': None,
- },
- {'name': 'actions',
- 'group': 'Actions',
- 'desc': 'Actions',
- 'tip': 'The number of requests for each action',
- 'value': None,
- },
- ]
-
def __init__(self, table, store, config):
"""Initialize the statistics.
@@ -124,7 +43,7 @@ class StatsLogger:
"""
# General
self.config = config
- self.startTime = datetime.now()
+ self.startTime = datetime.now().replace(microsecond=0)
self.reachable = False
# Routing Table
@@ -170,32 +89,72 @@ class StatsLogger:
self.keys, self.values = self.store.keyStats()
return (self.keys, self.values)
- def gather(self):
- """Gather all the statistics for the DHT.
+ def formatHTML(self):
+ """Gather statistics for the DHT and format them for display in a browser.
- @rtype: C{list} of C{dictionary}
- @return: each dictionary has keys describing the statistic:
- name, group, desc, tip, and value
+ @rtype: C{string}
+ @return: the stats, formatted for display in the body of an HTML page
"""
self.tableStats()
self.dbStats()
- stats = self._StatsTemplate[:]
- elapsed = datetime.now() - self.startTime
- for stat in stats:
- val = getattr(self, stat['name'], None)
- if stat['name'] == 'uptime':
- stat['value'] = elapsed
- elif stat['name'] == 'actions':
- stat['value'] = deepcopy(self.actions)
- elif stat['name'] == 'downSpeed':
- stat['value'] = self.downBytes / (elapsed.days*86400.0 + elapsed.seconds + elapsed.microseconds/1000000.0)
- elif stat['name'] == 'upSpeed':
- stat['value'] = self.upBytes / (elapsed.days*86400.0 + elapsed.seconds + elapsed.microseconds/1000000.0)
- elif val is not None:
- stat['value'] = val
-
- return stats
-
+ elapsed = datetime.now().replace(microsecond=0) - self.startTime
+ out = StringIO()
+ out.write('
DHT Statistics
\n')
+ out.write("\n\n")
+ out.write('\n')
+ out.write("\n")
+
+ # General
+ out.write("General | Value | \n")
+ out.write("Up time | " + str(elapsed) + ' | \n')
+ out.write("Reachable | " + str(self.reachable) + ' | \n')
+ out.write(" \n")
+ out.write(' | \n')
+ out.write("\n")
+
+ # Routing
+ out.write("Routing Table | Value | \n")
+ out.write("Number of nodes | " + str(self.nodes) + ' | \n')
+ out.write("Total number of users | " + str(self.users) + ' | \n')
+ out.write(" \n")
+ out.write(' | \n')
+ out.write("\n")
+
+ # Database
+ out.write("Database | Value | \n")
+ out.write("Keys | " + str(self.keys) + ' | \n')
+ out.write("Values | " + str(self.values) + ' | \n')
+ out.write(" \n")
+ out.write(" |
\n")
+ out.write("\n")
+ out.write("Transport | Packets | Bytes | Bytes/second | \n")
+ out.write("Downloaded | ")
+ out.write('' + str(self.downPackets) + ' | ')
+ out.write('' + str(self.downBytes) + ' | ')
+ out.write('%0.2f | \n' % (self.downBytes / (elapsed.days*86400.0 + elapsed.seconds), ))
+ out.write("Uploaded | ")
+ out.write('' + str(self.upPackets) + ' | ')
+ out.write('' + str(self.upBytes) + ' | ')
+ out.write('%0.2f | \n' % (self.upBytes / (elapsed.days*86400.0 + elapsed.seconds), ))
+ out.write(" \n")
+ out.write(" |
\n")
+ out.write("\n")
+
+ # Actions
+ out.write("Actions | Started | Sent | OK | Failed | Received | Error | \n")
+ actions = self.actions.keys()
+ actions.sort()
+ for action in actions:
+ out.write("" + action + " | ")
+ for i in xrange(6):
+ out.write("" + str(self.actions[action][i]) + " | ")
+ out.write(' \n')
+ out.write(" \n")
+ out.write(" |
\n")
+ out.write("
\n")
+
+ return out.getvalue()
+
#{ Called by the action
def startedAction(self, action):
"""Record that an action was started.