From 7f389dc76e3a62bbdca79396b1cf182eb0b4000a Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Sat, 25 Jun 2016 11:05:28 -0700 Subject: [PATCH] server: add --stats-file= scaffolding no actual stats yet --- src/wormhole/server/cli.py | 16 ++++++++++++++-- src/wormhole/server/cmd_server.py | 1 + src/wormhole/server/rendezvous.py | 25 ++++++++++++++++++++++--- src/wormhole/server/server.py | 4 ++-- 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/wormhole/server/cli.py b/src/wormhole/server/cli.py index 2408114..ae99760 100644 --- a/src/wormhole/server/cli.py +++ b/src/wormhole/server/cli.py @@ -48,8 +48,13 @@ def server(ctx): "--signal-error", is_flag=True, help="force all clients to fail with a message", ) +@click.option( + "--stats-file", default=None, type=type(u""), metavar="stats.json", + help="periodically write stats to a file for monitoring tools like Munin", +) @click.pass_obj -def start(cfg, signal_error, no_daemon, blur_usage, advertise_version, transit, rendezvous): +def start(cfg, signal_error, no_daemon, blur_usage, advertise_version, + transit, rendezvous, stats_file): """ Start a relay server """ @@ -60,6 +65,7 @@ def start(cfg, signal_error, no_daemon, blur_usage, advertise_version, transit, cfg.transit = str(transit) cfg.rendezvous = str(rendezvous) cfg.signal_error = signal_error + cfg.stats_file = stats_file start_server(cfg) @@ -92,8 +98,13 @@ def start(cfg, signal_error, no_daemon, blur_usage, advertise_version, transit, "--signal-error", is_flag=True, help="force all clients to fail with a message", ) +@click.option( + "--stats-file", default=None, type=type(u""), metavar="stats.json", + help="periodically write stats to a file for monitoring tools like Munin", +) @click.pass_obj -def restart(cfg, signal_error, no_daemon, blur_usage, advertise_version, transit, rendezvous): +def restart(cfg, signal_error, no_daemon, blur_usage, advertise_version, + transit, rendezvous, stats_file): """ Re-start a relay server """ @@ -104,6 +115,7 @@ def restart(cfg, signal_error, no_daemon, blur_usage, advertise_version, transit cfg.transit = str(transit) cfg.rendezvous = str(rendezvous) cfg.signal_error = signal_error + cfg.stats_file = stats_file restart_server(cfg) diff --git a/src/wormhole/server/cmd_server.py b/src/wormhole/server/cmd_server.py index f4fdac5..19035c4 100644 --- a/src/wormhole/server/cmd_server.py +++ b/src/wormhole/server/cmd_server.py @@ -15,6 +15,7 @@ class MyPlugin: self.args.advertise_version, "relay.sqlite", self.args.blur_usage, signal_error=self.args.signal_error, + stats_file=self.args.stats_file, ) class MyTwistdConfig(twistd.ServerOptions): diff --git a/src/wormhole/server/rendezvous.py b/src/wormhole/server/rendezvous.py index a62cc82..acb76c1 100644 --- a/src/wormhole/server/rendezvous.py +++ b/src/wormhole/server/rendezvous.py @@ -1,5 +1,5 @@ from __future__ import print_function, unicode_literals -import os, time, random, base64 +import os, time, random, base64, json from collections import namedtuple from twisted.python import log from twisted.application import service, internet @@ -478,15 +478,16 @@ class AppNamespace: channel._shutdown() class Rendezvous(service.MultiService): - def __init__(self, db, welcome, blur_usage): + def __init__(self, db, welcome, blur_usage, stats_file=None): service.MultiService.__init__(self) self._db = db self._welcome = welcome self._blur_usage = blur_usage + self._stats_file = stats_file log_requests = blur_usage is None self._log_requests = log_requests self._apps = {} - t = internet.TimerService(EXPIRATION_CHECK_PERIOD, self.prune_all_apps) + t = internet.TimerService(EXPIRATION_CHECK_PERIOD, self.timer) t.setServiceParent(self) def get_welcome(self): @@ -517,6 +518,10 @@ class Rendezvous(service.MultiService): apps.add(row["app_id"]) return apps + def timer(self): + self.prune_all_apps() + self.dump_stats(now=time.time(), validity=EXPIRATION_CHECK_PERIOD+60) + def prune_all_apps(self, now=None, old=None): # As with AppNamespace.prune_old_mailboxes, we log for now. log.msg("beginning app prune") @@ -528,6 +533,20 @@ class Rendezvous(service.MultiService): app.prune(now, old) log.msg("app prune ends, %d apps" % len(self._apps)) + def dump_stats(self, now, validity): + if not self._stats_file: + return + tmpfn = self._stats_file + ".tmp" + + data = {} + data["created"] = now + data["valid_until"] = now + validity + + with open(tmpfn, "wb") as f: + json.dump(data, f, indent=1) + f.write("\n") + os.rename(tmpfn, self._stats_file) + def stopService(self): # This forcibly boots any clients that are still connected, which # helps with unit tests that use threads for both clients. One client diff --git a/src/wormhole/server/server.py b/src/wormhole/server/server.py index efd8c78..b7b9f2a 100644 --- a/src/wormhole/server/server.py +++ b/src/wormhole/server/server.py @@ -28,7 +28,7 @@ class PrivacyEnhancedSite(server.Site): class RelayServer(service.MultiService): def __init__(self, rendezvous_web_port, transit_port, advertise_version, db_url=":memory:", blur_usage=None, - signal_error=None): + signal_error=None, stats_file=None): service.MultiService.__init__(self) self._blur_usage = blur_usage @@ -52,7 +52,7 @@ class RelayServer(service.MultiService): if signal_error: welcome["error"] = signal_error - rendezvous = Rendezvous(db, welcome, blur_usage) + rendezvous = Rendezvous(db, welcome, blur_usage, stats_file) rendezvous.setServiceParent(self) # for the pruning timer root = Root()