From 4b3adb3fcf761d600c148d052eceb853fe533891 Mon Sep 17 00:00:00 2001
From: Brian Warner <warner@allmydata.com>
Date: Tue, 29 Apr 2008 18:20:05 -0700
Subject: [PATCH] mutable stats: track mutable bytes published too

---
 src/allmydata/client.py       |  5 +++--
 src/allmydata/mutable/node.py | 12 ++++++------
 src/allmydata/web/status.py   | 16 ++++++++++------
 3 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/src/allmydata/client.py b/src/allmydata/client.py
index 87f77f48..cb96b495 100644
--- a/src/allmydata/client.py
+++ b/src/allmydata/client.py
@@ -307,8 +307,9 @@ class Client(node.Node, testutil.PollMixin):
         assert IMutableFileURI.providedBy(u), u
         return MutableFileNode(self).init_from_uri(u)
 
-    def notify_publish(self, publish_status):
-        self.getServiceNamed("mutable-watcher").notify_publish(publish_status)
+    def notify_publish(self, publish_status, size):
+        self.getServiceNamed("mutable-watcher").notify_publish(publish_status,
+                                                               size)
     def notify_retrieve(self, retrieve_status):
         self.getServiceNamed("mutable-watcher").notify_retrieve(retrieve_status)
     def notify_mapupdate(self, update_status):
diff --git a/src/allmydata/mutable/node.py b/src/allmydata/mutable/node.py
index 275ed377..b54bddb4 100644
--- a/src/allmydata/mutable/node.py
+++ b/src/allmydata/mutable/node.py
@@ -381,7 +381,7 @@ class MutableFileNode:
     def _upload(self, new_contents, servermap):
         assert self._pubkey, "update_servermap must be called before publish"
         p = Publish(self, servermap)
-        self._client.notify_publish(p.get_status())
+        self._client.notify_publish(p.get_status(), len(new_contents))
         return p.publish(new_contents)
 
 
@@ -410,16 +410,16 @@ class MutableWatcher(service.MultiService):
         while len(self._recent_mapupdate_status) > self.MAX_MAPUPDATE_STATUSES:
             self._recent_mapupdate_status.pop(0)
 
-    def notify_publish(self, p):
+    def notify_publish(self, p, size):
         self._all_publish_status[p] = None
         self._recent_publish_status.append(p)
         if self.stats_provider:
             self.stats_provider.count('mutable.files_published', 1)
-            # bytes_published can't be handled here, because the
+            # We must be told bytes_published as an argument, since the
             # publish_status does not yet know how much data it will be asked
-            # to send. TODO: figure out a clean way to do this that doesn't
-            # make MDMF harder.
-            #self.stats_provider.count('mutable.bytes_published', p.get_size())
+            # to send. When we move to MDMF we'll need to find a better way
+            # to handle this.
+            self.stats_provider.count('mutable.bytes_published', size)
         while len(self._recent_publish_status) > self.MAX_PUBLISH_STATUSES:
             self._recent_publish_status.pop(0)
 
diff --git a/src/allmydata/web/status.py b/src/allmydata/web/status.py
index e5903c9e..e3761e96 100644
--- a/src/allmydata/web/status.py
+++ b/src/allmydata/web/status.py
@@ -947,24 +947,28 @@ class Statistics(rend.Page):
         return str(data["stats"].get("load_monitor.max_load"))
 
     def render_uploads(self, ctx, data):
-        files = data["counters"].get("uploader.files_uploaded")
-        bytes = data["counters"].get("uploader.bytes_uploaded")
+        files = data["counters"].get("uploader.files_uploaded", 0)
+        bytes = data["counters"].get("uploader.bytes_uploaded", 0)
         return ("%s files / %s bytes (%s)" %
                 (files, bytes, abbreviate_size(bytes)))
 
     def render_downloads(self, ctx, data):
-        files = data["counters"].get("downloader.files_downloaded")
-        bytes = data["counters"].get("downloader.bytes_downloaded")
+        files = data["counters"].get("downloader.files_downloaded", 0)
+        bytes = data["counters"].get("downloader.bytes_downloaded", 0)
         return ("%s files / %s bytes (%s)" %
                 (files, bytes, abbreviate_size(bytes)))
 
     def render_publishes(self, ctx, data):
         files = data["counters"].get("mutable.files_published")
-        return "%s files" % (files,)
+        bytes = data["counters"].get("mutable.bytes_published", 0)
+        return "%s files / %s bytes (%s)" % (files, bytes,
+                                             abbreviate_size(bytes))
 
     def render_retrieves(self, ctx, data):
         files = data["counters"].get("mutable.files_retrieved")
-        return "%s files" % (files,)
+        bytes = data["counters"].get("mutable.bytes_retrieved", 0)
+        return "%s files / %s bytes (%s)" % (files, bytes,
+                                             abbreviate_size(bytes))
 
     def render_raw(self, ctx, data):
         raw = pprint.pformat(data)
-- 
2.45.2