Skip to content

Commit

Permalink
[postgres] Fix custom metrics collection
Browse files Browse the repository at this point in the history
Fix regression introduced by #1395.
The idea is that because the pre-processing function
`_process_customer_metrics`
was modifying "in-place" instance attributes, and for instance
converting the string "GAUGE" to the method "AgentCheck.gauge" at the
first pass, the second time it would expect to find a string and fail
when it encounters a method.
Instead we cache the pre-preprocessed dict the first time, and hit this
dictionnary in the next runs if it is present.
  • Loading branch information
LeoCavaille committed Apr 7, 2015
1 parent 1629ce0 commit 6bb8527
Showing 1 changed file with 19 additions and 10 deletions.
29 changes: 19 additions & 10 deletions checks.d/postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ def __init__(self, name, init_config, agentConfig, instances=None):
self.db_instance_metrics = []
self.db_bgw_metrics = []
self.replication_metrics = {}
self.custom_metrics = {}

def _get_version(self, key, db):
if key not in self.versions:
Expand Down Expand Up @@ -509,7 +510,12 @@ def get_connection(self, key, host, port, user, password, dbname, use_cached=Tru
self.dbs[key] = connection
return connection

def _process_customer_metrics(self,custom_metrics):
def _get_custom_metrics(self, custom_metrics, key):
# Pre-processed cached custom_metrics
if key in self.custom_metrics:
return self.custom_metrics[key]

# Otherwise pre-process custom metrics and verify definition
required_parameters = ("descriptors", "metrics", "query", "relation")

for m in custom_metrics:
Expand All @@ -520,14 +526,17 @@ def _process_customer_metrics(self,custom_metrics):

self.log.debug("Metric: {0}".format(m))

for k, v in m['metrics'].items():
if v[1].upper() not in ['RATE','GAUGE','MONOTONIC']:
raise CheckException("Collector method {0} is not known."\
"Known methods are RATE,GAUGE,MONOTONIC".format(
v[1].upper()))
for ref, (_, mtype) in m['metrics'].iteritems():
cap_mtype = mtype.upper()
if cap_mtype not in ('RATE', 'GAUGE', 'MONOTONIC'):
raise CheckException("Collector method {0} is not known."
" Known methods are RATE, GAUGE, MONOTONIC".format(cap_mtype))

m['metrics'][ref][1] = getattr(PostgreSql, cap_mtype)
self.log.debug("Method: %s" % (str(mtype)))

m['metrics'][k][1] = getattr(PostgreSql, v[1].upper())
self.log.debug("Method: %s" % (str(v[1])))
self.custom_metrics[key] = custom_metrics
return custom_metrics

def check(self, instance):
host = instance.get('host', '')
Expand All @@ -537,8 +546,6 @@ def check(self, instance):
tags = instance.get('tags', [])
dbname = instance.get('dbname', None)
relations = instance.get('relations', [])
custom_metrics = instance.get('custom_metrics') or []
self._process_customer_metrics(custom_metrics)

if relations and not dbname:
self.warning('"dbname" parameter must be set when using the "relations" parameter.')
Expand All @@ -548,6 +555,8 @@ def check(self, instance):

key = (host, port, dbname)

custom_metrics = self._get_custom_metrics(instance.get('custom_metrics', []), key)

# Clean up tags in case there was a None entry in the instance
# e.g. if the yaml contains tags: but no actual tags
if tags is None:
Expand Down

0 comments on commit 6bb8527

Please sign in to comment.