From b59c09fbfff0efb46e6a8bff064294acd9ee05a0 Mon Sep 17 00:00:00 2001 From: Edward Hope-Morley Date: Wed, 28 Jun 2023 12:42:22 +0100 Subject: [PATCH] Add some helper tools for viewing saved summaries --- pyproject.toml | 1 + scripts/hotsos-view | 3 ++ tools/__init__.py | 0 tools/summary/__init__.py | 0 tools/summary/diff | 15 +++++++ tools/summary/issues-and-bugs | 12 ++++++ tools/summary/less | 8 ++++ tools/summary/view.py | 77 +++++++++++++++++++++++++++++++++++ tox.ini | 7 +++- 9 files changed, 122 insertions(+), 1 deletion(-) create mode 100755 scripts/hotsos-view create mode 100644 tools/__init__.py create mode 100644 tools/summary/__init__.py create mode 100755 tools/summary/diff create mode 100755 tools/summary/issues-and-bugs create mode 100755 tools/summary/less create mode 100755 tools/summary/view.py diff --git a/pyproject.toml b/pyproject.toml index 4f6c963b4..a3c1f43a4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,3 +26,4 @@ dependencies = {file = ["requirements.txt"]} [project.scripts] hotsos = "hotsos.cli:main" +hotsos-view = "hotsos.tools.summary.view:main" diff --git a/scripts/hotsos-view b/scripts/hotsos-view new file mode 100755 index 000000000..ef3cd77a3 --- /dev/null +++ b/scripts/hotsos-view @@ -0,0 +1,3 @@ +#!/bin/bash +export PYTHONPATH=$PYTHONPATH:$(dirname $0)/.. +$(dirname $0)/../tools/summary/view.py $@ diff --git a/tools/__init__.py b/tools/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tools/summary/__init__.py b/tools/summary/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tools/summary/diff b/tools/summary/diff new file mode 100755 index 000000000..b60e71778 --- /dev/null +++ b/tools/summary/diff @@ -0,0 +1,15 @@ +#!/bin/bash +# +# Description: diff two hotsos summary outputs. +# +src=${1:-""} +dst=${2:-""} +format={3:-yaml} +if [[ -z $src ]] || [[ -z $dst ]]; then + echo "USAGE: `basename $0` " + exit +fi + +for f in `find $src -maxdepth 1 -name *summary.${format}`; do + diff -y $dst/$f $f| less +done diff --git a/tools/summary/issues-and-bugs b/tools/summary/issues-and-bugs new file mode 100755 index 000000000..b90f93d98 --- /dev/null +++ b/tools/summary/issues-and-bugs @@ -0,0 +1,12 @@ +#!/bin/bash +# +# Description: display only bugs and issues from summary outputs. +# +path=${1:-hotsos-output} +for f in `find $path -maxdepth 1 -name *summary.json`; do + clear + jq -r '"\nHostname: " + .system.hostname, + "Issues:", (.[]|to_entries[]|select(.key=="potential-issues")|.value|to_entries[]|.key, .value), + "Bugs:", (.[]|to_entries[]|select(.key=="known-bugs")|.value|to_entries[]|.key, .value)' $f + read -p "Next? [ENTER]" +done diff --git a/tools/summary/less b/tools/summary/less new file mode 100755 index 000000000..c7e6c82c0 --- /dev/null +++ b/tools/summary/less @@ -0,0 +1,8 @@ +#!/bin/bash +# +# Description: less each hotsos summary in path +# +path=${1:-hotsos-output} +for f in `find $path -maxdepth 1 -name *summary.yaml`; do + less $f +done diff --git a/tools/summary/view.py b/tools/summary/view.py new file mode 100755 index 000000000..b35ec3dbf --- /dev/null +++ b/tools/summary/view.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +""" +Create a structured summary of key information from hotsos summary outputs. +""" +import glob +import os +import json +import sys +import subprocess + +from hotsos.core import plugintools + + +def find_output(root): + if root is None: + root = '.' + + for entry in os.listdir(root): + if not os.path.isdir(entry): + continue + + results = glob.glob(os.path.join(entry, '*.json')) + if results: + return results[0] + + +if __name__ == "__main__": + if len(sys.argv) > 1: + path = os.path.join(sys.argv[1], '*.json') + else: + path = None + + path = find_output(None) + with open(path) as fd: + subprocess.call(['clear']) + s = json.loads(fd.read()) + print("host: {} ".format(s['system']['hostname'])) + print("date: {}".format(s['system']['date'])) + _enabled = [] + _services = {} + _has_bugs = {} + _has_potential_issues = {} + for plugin in plugintools.PLUGINS: + if plugin in s: + _enabled.append(plugin) + if 'services' in s[plugin]: + enabled = s[plugin]['services'] + enabled = enabled.get('systemd', {}) + _services[plugin] = enabled.get('enabled') + + if 'known-bugs' in s[plugin]: + _has_bugs.update(s[plugin]['known-bugs']) + + if 'potential-issues' in s[plugin]: + _has_potential_issues.update( + s[plugin]['potential-issues']) + +# print("enabled: {}".format(', '.join(sorted(_enabled)))) + print("services:") + for plugin, svcs in _services.items(): + print(" {}: {}".format(plugin, ', '.join(svcs))) + + if _has_bugs: + print("bugs:") + for btype, content in _has_bugs.items(): + print(" {}: {}\n".format(btype, '\n'.join(content))) + + if _has_potential_issues: + print("issues:") + for btype, content in _has_potential_issues.items(): + print(" {}:".format(btype)) + for msg in content: + print(" {}".format(msg)) + + input("\nNext? [ENTER]") + + print("") diff --git a/tox.ini b/tox.ini index 31c5698f1..889ddcf9e 100644 --- a/tox.ini +++ b/tox.ini @@ -81,7 +81,12 @@ commands = commands = sphinx-build -j auto -d {toxinidir}/doc/build/doctrees -b html {toxinidir}/doc/source doc/build/html [testenv:bashate] -commands = bashate --verbose {toxinidir}/tools/test/functest.sh +allowlist_externals = bashate +commands = bashate --verbose {toxinidir}/build.sh \ + {toxinidir}/tools/test/functest.sh \ + {toxinidir}/tools/summary/diff \ + {toxinidir}/tools/summary/less \ + {toxinidir}/tools/summary/issues-and-bugs [testenv:yamllint] commands = yamllint -c yamllintrc {toxinidir}/hotsos {toxinidir}/tests {posargs}