Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@sugarlabs.org>2013-11-14 09:58:07 (GMT)
committer Aleksey Lim <alsroot@sugarlabs.org>2013-11-14 09:58:07 (GMT)
commit793ec8514be49f836ae0559ad1396504470130c1 (patch)
treef9a615dddac150deda4d0bf5b4be1b887acd5d35
parent5b4263185727c05d39800d00b14930a132499125 (diff)
Rename "resolution" parameter to "records" in stats API call
-rw-r--r--sugar_network/node/routes.py37
-rw-r--r--sugar_network/node/stats_node.py47
-rwxr-xr-xtests/units/node/node.py4
3 files changed, 49 insertions, 39 deletions
diff --git a/sugar_network/node/routes.py b/sugar_network/node/routes.py
index 57c1dff..7b36b12 100644
--- a/sugar_network/node/routes.py
+++ b/sugar_network/node/routes.py
@@ -35,7 +35,7 @@ from sugar_network.toolkit.bundle import Bundle
from sugar_network.toolkit import pylru, http, coroutine, exception, enforce
-_MAX_STATS_LENGTH = 100
+_MAX_STAT_RECORDS = 128
_AUTH_POOL_SIZE = 1024
_logger = logging.getLogger('node.routes')
@@ -85,40 +85,27 @@ class NodeRoutes(model.VolumeRoutes, model.FrontRoutes):
return {'guid': self._guid, 'resources': documents}
@route('GET', cmd='stats', arguments={
- 'start': int, 'end': int, 'resolution': int, 'source': list},
+ 'start': int, 'end': int, 'records': int, 'source': list},
mime_type='application/json')
- def stats(self, start, end, resolution, source):
- if not source:
+ def stats(self, start, end, records, source):
+ if not source or records <= 0 or start > end:
return {}
enforce(self._stats is not None, 'Node stats is disabled')
- enforce(start < end, "Argument 'start' should be less than 'end'")
- enforce(resolution > 0, "Argument 'resolution' should be more than 0")
- min_resolution = (end - start) / _MAX_STATS_LENGTH
- if resolution < min_resolution:
- _logger.debug('Resulution is too short, use %s instead',
- min_resolution)
- resolution = min_resolution
+ if records > _MAX_STAT_RECORDS:
+ _logger.debug('Decrease %d stats records number to %d',
+ records, _MAX_STAT_RECORDS)
+ records = _MAX_STAT_RECORDS
+ resolution = (end - start) / records
- dbs = {}
+ stats = {}
for i in source:
enforce('.' in i, 'Misnamed source')
db_name, ds_name = i.split('.', 1)
- dbs.setdefault(db_name, []).append(ds_name)
- result = {}
+ stats.setdefault(db_name, []).append(ds_name)
- for rdb in self._stats.rrd:
- if rdb.name not in dbs:
- continue
- info = result[rdb.name] = []
- for ts, ds_values in rdb.get(start, end, resolution):
- values = {}
- for name in dbs[rdb.name]:
- values[name] = ds_values.get(name)
- info.append((ts, values))
-
- return result
+ return self._stats.report(stats, start, end, resolution)
@route('POST', ['user'], mime_type='application/json')
def register(self, request):
diff --git a/sugar_network/node/stats_node.py b/sugar_network/node/stats_node.py
index ec54fc3..19dd82e 100644
--- a/sugar_network/node/stats_node.py
+++ b/sugar_network/node/stats_node.py
@@ -40,6 +40,8 @@ stats_node_rras = Option(
],
type_cast=Option.list_cast, type_repr=Option.list_repr)
+_MAX_FRAME = 64
+
_logger = logging.getLogger('node.stats_node')
@@ -47,31 +49,40 @@ class Sniffer(object):
def __init__(self, volume):
path = join(node.stats_root.value, 'node')
- _logger.info('Start collecting node stats in %r', path)
+ _logger.info('Collect node stats in %r', path)
self._volume = volume
- self.rrd = Rrd(path, stats_node_step.value, stats_node_rras.value)
+ self._rrd = Rrd(path, stats_node_step.value, stats_node_rras.value)
self._stats = {}
- for cls in (_UserStats, _ContextStats, _ImplementationStats,
- _ReportStats, _ReviewStats, _FeedbackStats, _SolutionStats,
- _ArtifactStats, _CommentStats):
- self._stats[cls.RESOURCE] = cls(self._stats, volume)
+ for name, cls in _STATS.items():
+ self._stats[name] = cls(self._stats, volume)
def log(self, request):
- if request.cmd:
+ if request.cmd or request.resource in _STATS:
return
- stats = self._stats.get(request.resource)
- if stats is not None:
- stats.log(request)
+ self._stats[request.resource].log(request)
def commit(self, timestamp=None):
- _logger.heartbeat('Commit node stats')
+ _logger.trace('Commit node stats')
for resource, stats in self._stats.items():
values = stats.commit()
if values is not None:
- self.rrd[resource].put(values, timestamp=timestamp)
+ self._rrd[resource].put(values, timestamp=timestamp)
+
+ def report(self, dbs, start, end, resolution):
+ result = {}
+ for rdb in self._rrd:
+ if rdb.name not in dbs:
+ continue
+ info = result[rdb.name] = []
+ for ts, ds_values in rdb.get(start, end, resolution):
+ values = {}
+ for name in dbs[rdb.name]:
+ values[name] = ds_values.get(name)
+ info.append((ts, values))
+ return result
class _ObjectStats(object):
@@ -339,3 +350,15 @@ class _CommentStats(_Stats):
if request.content.get(owner):
self._stats[owner].commented += 1
break
+
+
+_STATS = {_UserStats.RESOURCE: _UserStats,
+ _ContextStats.RESOURCE: _ContextStats,
+ _ImplementationStats.RESOURCE: _ImplementationStats,
+ _ReportStats.RESOURCE: _ReportStats,
+ _ReviewStats.RESOURCE: _ReviewStats,
+ _FeedbackStats.RESOURCE: _FeedbackStats,
+ _SolutionStats.RESOURCE: _SolutionStats,
+ _ArtifactStats.RESOURCE: _ArtifactStats,
+ _CommentStats.RESOURCE: _CommentStats,
+ }
diff --git a/tests/units/node/node.py b/tests/units/node/node.py
index e019df4..b989ef1 100755
--- a/tests/units/node/node.py
+++ b/tests/units/node/node.py
@@ -124,7 +124,7 @@ class NodeTest(tests.Test):
(ts + 3, {'total': 3.0}),
],
},
- cp.stats(ts, ts + 3, 1, ['user.total']))
+ cp.stats(ts, ts + 3, 4, ['user.total']))
self.assertEqual({
'user': [
@@ -134,7 +134,7 @@ class NodeTest(tests.Test):
(ts + 12, {'total': 11.0}),
],
},
- cp.stats(ts, ts + 12, 3, ['user.total']))
+ cp.stats(ts, ts + 12, 4, ['user.total']))
def test_HandleDeletes(self):
volume = db.Volume('db', model.RESOURCES)