From 8377166430230a25228d2eba4888d601a59c84ec Mon Sep 17 00:00:00 2001
From: Jean-Paul Calderone <exarkun@twistedmatrix.com>
Date: Fri, 19 Nov 2021 10:46:09 -0500
Subject: [PATCH] Metrics: Implement regular writing of metrics to .prom file

---
 src/_zkapauthorizer/_plugin.py           | 15 +++++++++++----
 src/_zkapauthorizer/tests/test_plugin.py | 11 ++++++++---
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/src/_zkapauthorizer/_plugin.py b/src/_zkapauthorizer/_plugin.py
index 88998b0..e0c3f54 100644
--- a/src/_zkapauthorizer/_plugin.py
+++ b/src/_zkapauthorizer/_plugin.py
@@ -27,7 +27,9 @@ from allmydata.client import _Client
 from allmydata.interfaces import IAnnounceableStorageServer, IFoolscapStoragePlugin
 from allmydata.node import MissingConfigEntry
 from challenge_bypass_ristretto import SigningKey
-from prometheus_client import CollectorRegistry
+from isodate import parse_duration
+from prometheus_client import CollectorRegistry, write_to_textfile
+from twisted.internet import task
 from twisted.internet.defer import succeed
 from twisted.logger import Logger
 from twisted.python.filepath import FilePath
@@ -101,11 +103,16 @@ class ZKAPAuthorizer(object):
         if reactor is None:
             from twisted.internet import reactor
         registry = CollectorRegistry()
-        # schedule_writing(registry)
         kwargs = configuration.copy()
 
-        kwargs.pop(u"prometheus-metrics-path", None)
-        kwargs.pop(u"prometheus-metrics-interval", None)
+        # If metrics are desired, schedule their writing to disk.
+        metrics_interval = kwargs.pop(u"prometheus-metrics-interval", None)
+        metrics_path = kwargs.pop(u"prometheus-metrics-path", None)
+        if metrics_interval is not None and metrics_path is not None:
+            t = task.LoopingCall(lambda: write_to_textfile(metrics_path, registry))
+            t.clock = reactor
+            t.start(parse_duration(metrics_interval).total_seconds())
+
         root_url = kwargs.pop(u"ristretto-issuer-root-url")
         pass_value = int(kwargs.pop(u"pass-value", BYTES_PER_PASS))
         signing_key = load_signing_key(
diff --git a/src/_zkapauthorizer/tests/test_plugin.py b/src/_zkapauthorizer/tests/test_plugin.py
index 3060075..f5fd113 100644
--- a/src/_zkapauthorizer/tests/test_plugin.py
+++ b/src/_zkapauthorizer/tests/test_plugin.py
@@ -290,10 +290,15 @@ class ServerPluginTests(TestCase):
             )
         )
         registry = announceable.storage_server._registry
-        Gauge("foo", "bar", registry=registry).set(1)
 
-        clock.advance(metrics_interval.total_seconds())
-        self.assertThat(metrics_path, FileContains("foo 1"))
+        g = Gauge("foo", "bar", registry=registry)
+        for i in range(2):
+            g.set(i)
+
+            clock.advance(metrics_interval.total_seconds())
+            self.assertThat(
+                metrics_path, FileContains(matcher=Contains("foo {}".format(i)))
+            )
 
 
 tahoe_configs_with_dummy_redeemer = tahoe_configs(client_dummyredeemer_configurations())
-- 
GitLab