From 74c5c00305f6a047900a5ed2ff039cbfb066a398 Mon Sep 17 00:00:00 2001 From: Benjamin Schanzel Date: Tue, 4 Jan 2022 14:12:30 +0100 Subject: [PATCH] Export current tenant limit stats This adds a new statsd gauge which, in addition to the existing provider limits, exports the currently configured tenant limits. This is in the form ``nodepool.tenant_limits.TENANT.[cores,ram,instances]``. Change-Id: I8e10a0974210d25d071dbbd63849a921fc8b79a2 --- doc/source/operation.rst | 11 +++++++++++ nodepool/launcher.py | 2 ++ nodepool/stats.py | 24 ++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/doc/source/operation.rst b/doc/source/operation.rst index fa79e419f..db21fc02a 100644 --- a/doc/source/operation.rst +++ b/doc/source/operation.rst @@ -495,6 +495,17 @@ The following metrics are produced by a ``nodepool-launcher`` process: Number of nodes with a specific label in a specific state. See :ref:`nodepool.nodes ` for a list of possible states. +.. zuul:stat:: nodepool.tenant_limits.. + :type: guage + + The currently configured resource limits of a tenant. + + limit can be: + + * cores + * instances + * ram + Provider Metrics ^^^^^^^^^^^^^^^^ diff --git a/nodepool/launcher.py b/nodepool/launcher.py index c6f619f6e..7e80da253 100644 --- a/nodepool/launcher.py +++ b/nodepool/launcher.py @@ -338,6 +338,8 @@ class PoolWorker(threading.Thread, stats.StatsReporter): self.updateProviderLimits( self.nodepool.config.providers.get(self.provider_name)) + self.updateTenantLimits( + self.nodepool.config.tenant_resource_limits) if not self.paused_handler: while not self._assignHandlers(): diff --git a/nodepool/stats.py b/nodepool/stats.py index 6331e097a..229a18d8b 100644 --- a/nodepool/stats.py +++ b/nodepool/stats.py @@ -41,6 +41,10 @@ def get_client(): return None +def normalize_statsd_name(name): + return name.replace('.', '_').replace(':', '_') + + class StatsReporter(object): ''' Class adding statsd reporting functionality. @@ -72,8 +76,7 @@ class StatsReporter(object): if self.handler.request.requestor: # Replace '.' which is a graphite hierarchy, and ':' which is # a statsd delimeter. - requestor = self.handler.request.requestor.replace('.', '_') - requestor = requestor.replace(':', '_') + requestor = normalize_statsd_name(self.handler.request.requestor) keys.append('nodepool.launch.requestor.%s.%s' % (requestor, subkey)) @@ -159,3 +162,20 @@ class StatsReporter(object): pipeline.gauge(key, max_servers) pipeline.send() + + def updateTenantLimits(self, tenant_limits): + if not self._statsd: + return + + pipeline = self._statsd.pipeline() + # nodepool.tenant_limits.TENANT.[cores,ram,instances] + key_template = 'nodepool.tenant_limits.%s.%s' + for tenant, limits in tenant_limits.items(): + for k, lim in limits.items(): + # normalize for statsd name, as parts come from arbitrary + # user config + tenant = normalize_statsd_name(tenant) + k = normalize_statsd_name(k) + key = key_template % (tenant, k) + pipeline.gauge(key, lim) + pipeline.send()