From a7b4600d0cf5d48d718385d9dc38bbf450556f10 Mon Sep 17 00:00:00 2001 From: Andreas Maier Date: Wed, 15 Nov 2023 18:01:49 +0100 Subject: [PATCH] Add backing adapter/port as labels to NIC metrics Details: * If metric group 'partition-attached-network-interface' is defined to be fetched, the backing adapters of the respective NICs are determined and stored as dynamic attributes 'adapter_name' and 'port_index' on the zhmcclient.Nic object that is put into the uri2resource dict. * In addition, Jinja2 functions 'adapter_name()' and 'adapter_port()' have been implemented for use by label value definitions of that metric group. These functions look up the zhmcclient.Nic object from the uri2resource dict and get the adapter name and port index from its newly added dynamic attributes. * Finally, two new labels 'adapter' and 'port' have been added to the metric group 'partition-attached-network-interface', that use these two new Jinja2 functions. Signed-off-by: Andreas Maier --- docs/changes.rst | 3 + examples/metrics.yaml | 4 + .../zhmc_prometheus_exporter.py | 77 ++++++++++++++++++- 3 files changed, 82 insertions(+), 2 deletions(-) diff --git a/docs/changes.rst b/docs/changes.rst index 1246da49..1797eee4 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -103,6 +103,9 @@ Released: not yet file, because one possible reason for that is that a newer metrics.yaml file is being used. (issue #379) +* Added adapter name and port index as two new labels 'adapter' and 'port' to + metric group 'partition-attached-network-interface'. (issue #347) + **Cleanup:** **Known issues:** diff --git a/examples/metrics.yaml b/examples/metrics.yaml index a0838fe6..4d0406db 100644 --- a/examples/metrics.yaml +++ b/examples/metrics.yaml @@ -125,6 +125,10 @@ metric_groups: value: "resource_obj.manager.parent.name" - name: nic value: "resource_obj.name" + - name: adapter + value: "adapter_name(resource_obj)" + - name: port + value: "adapter_port(resource_obj)" partition-resource: type: resource diff --git a/zhmc_prometheus_exporter/zhmc_prometheus_exporter.py b/zhmc_prometheus_exporter/zhmc_prometheus_exporter.py index 9e07aaf3..1220ca45 100755 --- a/zhmc_prometheus_exporter/zhmc_prometheus_exporter.py +++ b/zhmc_prometheus_exporter/zhmc_prometheus_exporter.py @@ -752,6 +752,26 @@ def create_metrics_context(session, yaml_metric_groups, hmc_version): "newer than the exporter program?)". format(rp=resource_path, mg=metric_group)) + # Fetch backing adapters of NICs, if needed + if 'partition-attached-network-interface' in fetched_hmc_metric_groups: + cpcs = client.cpcs.list() + for cpc in cpcs: + partitions = cpc.partitions.list() + for partition in partitions: + nics = partition.nics.list() + for nic in nics: + + logprint(logging.INFO, PRINT_V, + "Getting backing adapter port for NIC {}.{}.{}". + format(cpc.name, partition.name, nic.name)) + adapter_name, port_index = get_backing_adapter_info(nic) + + # Store the adapter port data as dynamic attributes on the + # Nic object in the uri2resource dict. + nic.adapter_name = adapter_name + nic.port_index = port_index + uri2resource[nic.uri] = nic + return context, resources, uri2resource @@ -900,6 +920,35 @@ def expand_global_label_value( return str(value) +def get_backing_adapter_info(nic): + """ + Return backing adapter and port of the specified NIC. + + Returns: + tuple(adapter_name, port_index) + """ + + session = nic.manager.session + + # Handle vswitch-based NIC (OSA, HS) + try: + vswitch_uri = nic.get_property('virtual-switch-uri') + except KeyError: + pass + else: + vswitch_props = session.get(vswitch_uri) + adapter_uri = vswitch_props['backing-adapter-uri'] + adapter_props = session.get(adapter_uri) + return adapter_props['name'], vswitch_props['port'] + + # Handle adapter-based NIC (RoCE, CNA) + port_uri = nic.get_property('network-adapter-port-uri') + port_props = session.get(port_uri) + adapter_uri = port_props['parent'] + adapter_props = session.get(adapter_uri) + return adapter_props['name'], port_props['index'] + + def expand_group_label_value( env, label_name, group_name, item_value, resource_obj, uri2resource, metric_values=None): @@ -913,6 +962,16 @@ def uri2resource_func(uri): def uris2resources_func(uris): return [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] + 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] + return str(nic_org.port_index) + try: func = env.compile_expression(item_value) except jinja2.TemplateSyntaxError as exc: @@ -926,7 +985,9 @@ def uris2resources_func(uris): resource_obj=resource_obj, metric_values=metric_values, uri2resource=uri2resource_func, - uris2resources=uris2resources_func) + uris2resources=uris2resources_func, + adapter_name=adapter_name_func, + adapter_port=adapter_port_func) # pylint: disable=broad-exception-caught,broad-except except Exception as exc: logprint(logging.WARNING, PRINT_V, @@ -950,6 +1011,16 @@ def uri2resource_func(uri): def uris2resources_func(uris): return [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] + 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] + return str(nic_org.port_index) + try: func = env.compile_expression(item_value) except jinja2.TemplateSyntaxError as exc: @@ -963,7 +1034,9 @@ def uris2resources_func(uris): resource_obj=resource_obj, metric_values=metric_values, uri2resource=uri2resource_func, - uris2resources=uris2resources_func) + uris2resources=uris2resources_func, + adapter_name=adapter_name_func, + adapter_port=adapter_port_func) # pylint: disable=broad-exception-caught,broad-except except Exception as exc: logprint(logging.WARNING, PRINT_V,