Skip to content

Commit

Permalink
Fixed warning about ignoring label 'adapter/port'
Browse files Browse the repository at this point in the history
Details:

* Fixed warning about ignoring label 'adapter/port' on metric group
  'partition-attached-network-interface' due to error in rendering the Jinja2
  expression for a label value. (issue #450)

Signed-off-by: Andreas Maier <[email protected]>
  • Loading branch information
andy-maier committed Feb 23, 2024
1 parent 8d53f6b commit 9e3e12a
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 31 deletions.
4 changes: 4 additions & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ Released: not yet
Disabled Sphinx runs on Python <=3.7 in order to no longer having to deal
with older Sphinx versions. (issue #444)

* Fixed warning about ignoring label 'adapter/port' on metric group
'partition-attached-network-interface' due to error in rendering the Jinja2
expression for a label value. (issue #450)

**Enhancements:**

**Cleanup:**
Expand Down
10 changes: 5 additions & 5 deletions tests/test_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ def setup_metrics_context():
"metric-groups": ["dpm-system-usage-overview"]})
resources = {}
resources["cpc-resource"] = [client.cpcs.find(name='cpc_1')]
return context, resources
return session, context, resources


def teardown_metrics_context(context):
Expand All @@ -292,7 +292,7 @@ def test_retrieve_metrics(self):
# pylint: disable=no-self-use
"""Tests retrieve_metrics()"""

context, _ = setup_metrics_context()
_, context, _ = setup_metrics_context()

metrics_object = zhmc_prometheus_exporter.retrieve_metrics(context)

Expand Down Expand Up @@ -354,12 +354,12 @@ def test_build_family_objects(self):
hmc_version = '2.15.0'
se_versions = {'cpc_1': '2.15.0'}

context, resources = setup_metrics_context()
session, context, resources = setup_metrics_context()
metrics_object = zhmc_prometheus_exporter.retrieve_metrics(context)

families = zhmc_prometheus_exporter.build_family_objects(
metrics_object, yaml_metric_groups, yaml_metrics, 'file',
extra_labels, hmc_version, se_versions)
extra_labels, hmc_version, se_versions, session)

assert len(families) == 1
assert "zhmc_pre_processor_usage" in families
Expand All @@ -380,7 +380,7 @@ def test_build_family_objects(self):

families = zhmc_prometheus_exporter.build_family_objects_res(
resources, yaml_metric_groups, yaml_metrics, 'file',
extra_labels, hmc_version, se_versions)
extra_labels, hmc_version, se_versions, session)

assert len(families) == 1
assert "zhmc_foo_name" in families
Expand Down
126 changes: 100 additions & 26 deletions zhmc_prometheus_exporter/zhmc_prometheus_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -956,27 +956,96 @@ def get_backing_adapter_info(nic):
return adapter_props['name'], port_props['index']


def uri_to_resource(client, uri2resource, uri):
"""
Look up a zhmcclient resource object from a URI, using the uri2resoure
dict. If the URI is not in the dict, determine the resource object from
the URI and add it to the dict. This supports the addition of resources
after the start of the exporter.
The following URIs are supported (these are all that are
currently used by uri2resource and related functions in the default
metric definition file):
* nic - used in nic metric group (to get back to original NIC object that
has adapter_name/port as additonal attributes)
* storage groups - used in partition metric group
* cpc - used in storage-group and storage-volume metric groups
"""

try:
resource = uri2resource[uri]
except KeyError:
# The uri2resource dict was created at startup time of the
# exporter and was filled with all resources (of types the exporter
# supports) that existed at that time. The KeyError means that
# a new resource came into existence since then.

m = re.match(r'(/api/partitions/[a-f0-9\-]+)/nics/[a-f0-9\-]+$', uri)
if m is not None:
# Resource URI is for a NIC
partition_uri = m.group(1)
partition_props = client.get(partition_uri)
cpc_uri = partition_props.properties['parent']
cpc = client.cpcs.resource_object(cpc_uri)
partition = cpc.partitions.resource_object(partition_uri)
nic = partition.nics.resource_object(uri)
logprint(logging.INFO, PRINT_V,
"Adding NIC {}.{}.{} after exporter start for fast "
"lookup".format(cpc.name, partition.name, nic.name))
uri2resource[uri] = nic
return nic

m = re.match(r'(/api/storage-groups/[a-f0-9\-]+)$', uri)
if m is not None:
# Resource URI is for a storage group
stogrp = client.storage_groups.resource_object(uri)
logprint(logging.INFO, PRINT_V,
"Adding storage group {}.{} after exporter start for "
"fast lookup".format(cpc.name, stogrp.name))
uri2resource[uri] = stogrp
return stogrp

m = re.match(r'(/api/cpcs/[a-f0-9\-]+)$', uri)
if m is not None:
# Resource URI is for a CPC
cpc = client.cpcs.resource_object(uri)
logprint(logging.INFO, PRINT_V,
"Adding CPC {} after exporter start for fast lookup".
format(cpc.name))
uri2resource[uri] = cpc
return cpc

raise OtherError(
"Resource type for URI {u} is not supported for dynamic addition "
"of resources after start of exporter".format(u=uri))

return resource


def expand_group_label_value(
env, label_name, group_name, item_value, resource_obj,
env, label_name, group_name, item_value, client, resource_obj,
uri2resource, metric_values=None):
"""
Expand a Jinja2 expression on a label value, for a metric group label.
"""

def uri2resource_func(uri):
return uri2resource[uri]
return uri_to_resource(client, uri2resource, uri)

def uris2resources_func(uris):
return [uri2resource[uri] for uri in uris]
return [uri_to_resource(client, uri2resource, uri) for uri in uris]

def adapter_name_func(nic):
# Get the Nic object that has the dynamic attributes with adapter info
nic_org = uri2resource[nic.uri]
# Get the original Nic object that has the dynamic attributes with the
# adapter info
nic_org = uri_to_resource(client, uri2resource, nic.uri)
return nic_org.adapter_name

def adapter_port_func(nic):
# Get the Nic object that has the dynamic attributes with adapter info
nic_org = uri2resource[nic.uri]
# Get the original Nic object that has the dynamic attributes with the
# adapter info
nic_org = uri_to_resource(client, uri2resource, nic.uri)
return str(nic_org.port_index)

try:
Expand Down Expand Up @@ -1006,26 +1075,28 @@ def adapter_port_func(nic):


def expand_metric_label_value(
env, label_name, metric_exporter_name, item_value, resource_obj,
uri2resource, metric_values=None):
env, label_name, metric_exporter_name, item_value, client,
resource_obj, uri2resource, metric_values=None):
"""
Expand a Jinja2 expression on a label value, for a metric label.
"""

def uri2resource_func(uri):
return uri2resource[uri]
return uri_to_resource(client, uri2resource, uri)

def uris2resources_func(uris):
return [uri2resource[uri] for uri in uris]
return [uri_to_resource(client, uri2resource, uri) for uri in uris]

def adapter_name_func(nic):
# Get the Nic object that has the dynamic attributes with adapter info
nic_org = uri2resource[nic.uri]
# Get the original Nic object that has the dynamic attributes with the
# adapter info
nic_org = uri_to_resource(client, uri2resource, nic.uri)
return nic_org.adapter_name

def adapter_port_func(nic):
# Get the Nic object that has the dynamic attributes with adapter info
nic_org = uri2resource[nic.uri]
# Get the original Nic object that has the dynamic attributes with the
# adapter info
nic_org = uri_to_resource(client, uri2resource, nic.uri)
return str(nic_org.port_index)

try:
Expand Down Expand Up @@ -1072,7 +1143,7 @@ def cpc_from_resource(resource):

def build_family_objects(
metrics_object, yaml_metric_groups, yaml_metrics, metrics_filename,
extra_labels, hmc_version, se_versions, resource_cache=None,
extra_labels, hmc_version, se_versions, session, resource_cache=None,
uri2resource=None):
"""
Go through all retrieved metrics and build the Prometheus Family objects.
Expand All @@ -1087,6 +1158,7 @@ def build_family_objects(
GaugeMetricFamily object
"""
env = jinja2.Environment()
client = zhmcclient.Client(session)

family_objects = {}
for metric_group_value in metrics_object.metric_group_values:
Expand Down Expand Up @@ -1135,8 +1207,8 @@ def build_family_objects(
label_name = item['name']
item_value = item['value']
label_value = expand_group_label_value(
env, label_name, metric_group, item_value, resource,
uri2resource, metric_values)
env, label_name, metric_group, item_value, client,
resource, uri2resource, metric_values)
if label_value is not None:
mg_labels[label_name] = label_value

Expand Down Expand Up @@ -1187,7 +1259,8 @@ def build_family_objects(
item_value = item['value']
label_value = expand_metric_label_value(
env, label_name, yaml_metric["exporter_name"],
item_value, resource, uri2resource, metric_values)
item_value, client, resource, uri2resource,
metric_values)
if label_value is not None:
labels[label_name] = label_value

Expand Down Expand Up @@ -1222,7 +1295,7 @@ def build_family_objects(

def build_family_objects_res(
resources, yaml_metric_groups, yaml_metrics, metrics_filename,
extra_labels, hmc_version, se_versions, resource_cache=None,
extra_labels, hmc_version, se_versions, session, resource_cache=None,
uri2resource=None):
"""
Go through all auto-updated resources and build the Prometheus Family
Expand All @@ -1238,6 +1311,7 @@ def build_family_objects_res(
GaugeMetricFamily object
"""
env = jinja2.Environment()
client = zhmcclient.Client(session)

family_objects = {}
for metric_group, res_list in resources.items():
Expand Down Expand Up @@ -1286,8 +1360,8 @@ def build_family_objects_res(
label_name = item['name']
item_value = item['value']
label_value = expand_group_label_value(
env, label_name, metric_group, item_value, resource,
uri2resource)
env, label_name, metric_group, item_value, client,
resource, uri2resource)
if label_value is not None:
mg_labels[label_name] = label_value

Expand Down Expand Up @@ -1422,8 +1496,8 @@ def build_family_objects_res(
label_name = item['name']
item_value = item['value']
label_value = expand_metric_label_value(
env, label_name, exporter_name, item_value, resource,
uri2resource)
env, label_name, exporter_name, item_value, client,
resource, uri2resource)
if label_value is not None:
labels[label_name] = label_value

Expand Down Expand Up @@ -1547,15 +1621,15 @@ def collect(self):
metrics_object, self.yaml_metric_groups,
self.yaml_metrics, self.filename_metrics,
self.extra_labels, self.hmc_version, self.se_versions,
self.resource_cache, self.uri2resource)
self.session, self.resource_cache, self.uri2resource)

logprint(logging.DEBUG, None,
"Building family objects for resource metrics")
family_objects.update(build_family_objects_res(
self.resources, self.yaml_metric_groups,
self.yaml_metrics, self.filename_metrics,
self.extra_labels, self.hmc_version, self.se_versions,
self.resource_cache, self.uri2resource))
self.session, self.resource_cache, self.uri2resource))

logprint(logging.DEBUG, None,
"Returning family objects")
Expand Down

0 comments on commit 9e3e12a

Please sign in to comment.