From 09ef63c77668e48003eb7da541fe8589f6b28de6 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone <exarkun@twistedmatrix.com> Date: Tue, 7 Dec 2021 13:14:39 -0500 Subject: [PATCH] do not let write_to_textfile raise an exception to LoopingCall Also make the metrics path's parent directory if necessary --- src/_zkapauthorizer/_plugin.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/_zkapauthorizer/_plugin.py b/src/_zkapauthorizer/_plugin.py index 2670c12..6d7a705 100644 --- a/src/_zkapauthorizer/_plugin.py +++ b/src/_zkapauthorizer/_plugin.py @@ -27,6 +27,7 @@ from allmydata.client import _Client from allmydata.interfaces import IAnnounceableStorageServer, IFoolscapStoragePlugin from allmydata.node import MissingConfigEntry from challenge_bypass_ristretto import SigningKey +from eliot import start_action from prometheus_client import CollectorRegistry, write_to_textfile from twisted.internet import task from twisted.internet.defer import succeed @@ -109,7 +110,8 @@ class ZKAPAuthorizer(object): 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)) + FilePath(metrics_path).parent().makedirs(ignoreExistingDirectory=True) + t = task.LoopingCall(make_safe_writer(metrics_path, registry)) t.clock = reactor t.start(int(metrics_interval)) @@ -175,6 +177,25 @@ class ZKAPAuthorizer(object): ) +def make_safe_writer(metrics_path, registry): + # type: (str, CollectorRegistry) -> Callable[[], None] + """ + Make a no-argument callable that writes metrics from the given registry to + the given path. The callable will log errors writing to the path and not + raise exceptions. + """ + + def safe_writer(): + try: + with start_action( + action_type=u"zkapauthorizer:metrics:write-to-textfile", + metrics_path=metrics_path, + ): + write_to_textfile(metrics_path, registry) + except Exception: + pass + + _init_storage = _Client.__dict__["init_storage"] -- GitLab