Add script to shot tempalte coverage

* Add a script to compare the defined metrics with those used in the
  Zabbix template.

* Add a Makefile target to run the above script.
This commit is contained in:
James Campbell 2025-10-09 02:21:17 -04:00
parent ab039dc412
commit 3ade30c04a
Signed by: james
GPG Key ID: 2287C33A40DC906A
2 changed files with 134 additions and 0 deletions

View File

@ -110,6 +110,11 @@ endif
query-tests:
cd tests ; ./run-tests.sh
# Compare the sample metrics with the Zabbix template
template-coverage:
$(PYTHON) zabbix_templates/coverage.py sample-config/pgmon-metrics.yml zabbix_templates/pgmon_templates.yaml
# Install the script at the specified base directory (common components)
install-common:
# Set up directories

129
zabbix_templates/coverage.py Executable file
View File

@ -0,0 +1,129 @@
#!/usr/bin/env python3
# Compare the items defined in a Zabbix template with the metrics defined in a config file.
import sys
import yaml
# Special built in metrics
SPECIAL = {
"agent_version",
"latest_version_info"
}
class NonMetricItemError(Exception):
"""
A given item does not directly use a metric
"""
def read_metrics(file):
"""
Read the metrics from a config file and return the list of names
params:
file: the name of the file to read
returns:
list of metric named defined in the file
raises:
yaml.parser.ParserError: invalid yaml file
"""
names = set()
config = None
with open(file, "r", encoding="utf-8") as f:
config = yaml.safe_load(f)
try:
for m in config["metrics"].keys():
names.add(m)
except KeyError:
pass
return names
def extract_metric(item):
"""
Extract the metric from an item definition
params:
item: the item/discovery/prototype definition dict
returns:
the name of the metric used in the item
raises:
NonMetricItemError: the item does not directly use a metric
"""
try:
if item["type"] == "HTTP_AGENT":
url = item["url"]
if url.startswith("http://localhost:{$AGENT_PORT}"):
return url.split("/")[-1]
except KeyError:
raise NonMetricItemError()
raise NonMetricItemError()
def read_template(file):
"""
Read the items from a Zabbix template and return the list of metric names
params:
file: the name of the file to read
returns:
list of metric named used in the file
raises:
yaml.parser.ParserError: invalid yaml file
"""
names = set()
config = None
with open(file, "r", encoding="utf-8") as f:
config = yaml.safe_load(f)
try:
for template in config["zabbix_export"]["templates"]:
for item in template["items"]:
try:
names.add(extract_metric(item))
except NonMetricItemError:
pass
for rule in template["discovery_rules"]:
try:
names.add(extract_metric(rule))
except NonMetricItemError:
pass
for proto in rule["item_prototypes"]:
try:
names.add(extract_metric(proto))
except NonMetricItemError:
pass
except KeyError:
pass
return names
if __name__ == '__main__':
config_file = sys.argv[1]
config_metrics = read_metrics(config_file)
template_file = sys.argv[2]
template_metrics = read_template(template_file) - SPECIAL
config_only = config_metrics - template_metrics
template_only = template_metrics - config_metrics
print("Config only: {}".format(sorted(list(config_only))))
print("Template only: {}".format(sorted(list(template_only))))