webapi: introducer stats: add 'announcement_distinct_hosts' to the t=json form, to...
authorBrian Warner <warner@allmydata.com>
Tue, 18 Nov 2008 22:30:15 +0000 (15:30 -0700)
committerBrian Warner <warner@allmydata.com>
Tue, 18 Nov 2008 22:30:15 +0000 (15:30 -0700)
docs/frontends/webapi.txt
src/allmydata/test/test_system.py
src/allmydata/web/introweb.py

index 59ac9ed1b518b5049aba5d0d6694f22572d0376c..a91a478d0bbc7ce3f150e2bcb48ae7f77da55b11 100644 (file)
@@ -1162,7 +1162,22 @@ GET /   (introducer status)
 
  By adding "?t=json" to the URL, the node will return a JSON-formatted
  dictionary of stats values, which can be used to produce graphs of connected
- clients over time.
+ clients over time. This dictionary has the following keys:
+
+  ["subscription_summary"] : a dictionary mapping service name (like
+                             "storage") to an integer with the number of
+                             clients that have subscribed to hear about that
+                             service
+  ["announcement_summary"] : a dictionary mapping service name to an integer
+                             with the number of servers which are announcing
+                             that service
+  ["announcement_distinct_hosts"] : a dictionary mapping service name to an
+                                    integer which represents the number of
+                                    distinct hosts that are providing that
+                                    service. If two servers have announced
+                                    FURLs which use the same hostnames (but
+                                    different ports and tubids), they are
+                                    considered to be on the same host.
 
 
 == Static Files in /public_html ==
index baa06b186a41c0a2822f781b87bd5d4920a181e6..716544ee14a9bbe2b45659067c4eaf633748283a 100644 (file)
@@ -802,6 +802,8 @@ class SystemTest(SystemTestMixin, unittest.TestCase):
                                      {"storage": 5})
                 self.failUnlessEqual(data["announcement_summary"],
                                      {"storage": 5, "stub_client": 5})
+                self.failUnlessEqual(data["announcement_distinct_hosts"],
+                                     {"storage": 1, "stub_client": 1})
             except unittest.FailTest:
                 print
                 print "GET %s?t=json output was:" % self.introweb_url
index 13e48384ba47eb83c9f7cc1ea6a1e402823f6637..f1a6ad02638ddb68f3ddc3d69deccb3efdcc6ff9 100644 (file)
@@ -31,12 +31,32 @@ class IntroducerRoot(rend.Page):
         res["subscription_summary"] = subscription_summary
 
         announcement_summary = {}
+        service_hosts = {}
         for (ann,when) in i.get_announcements().values():
             (furl, service_name, ri_name, nickname, ver, oldest) = ann
             if service_name not in announcement_summary:
                 announcement_summary[service_name] = 0
             announcement_summary[service_name] += 1
+            if service_name not in service_hosts:
+                service_hosts[service_name] = set()
+            # it's nice to know how many distinct hosts are available for
+            # each service. We define a "host" by a set of addresses
+            # (hostnames or ipv4 addresses), which we extract from the
+            # connection hints. In practice, this is usually close
+            # enough: when multiple services are run on a single host,
+            # they're usually either configured with the same addresses,
+            # or setLocationAutomatically picks up the same interfaces.
+            locations = SturdyRef(furl).getTubRef().getLocations()
+            # list of tuples, ("ipv4", host, port)
+            host = frozenset([hint[1]
+                              for hint in locations
+                              if hint[0] == "ipv4"])
+            service_hosts[service_name].add(host)
         res["announcement_summary"] = announcement_summary
+        distinct_hosts = dict([(name, len(hosts))
+                               for (name, hosts)
+                               in service_hosts.iteritems()])
+        res["announcement_distinct_hosts"] = distinct_hosts
 
         return simplejson.dumps(res, indent=1) + "\n"