Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some helper tools for viewing saved summaries #744

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ dependencies = {file = ["requirements.txt"]}

[project.scripts]
hotsos = "hotsos.cli:main"
hotsos-view = "hotsos.tools.summary.view:main"
3 changes: 3 additions & 0 deletions scripts/hotsos-view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash
export PYTHONPATH=$PYTHONPATH:$(dirname $0)/..
$(dirname $0)/../tools/summary/view.py $@
Empty file added tools/__init__.py
Empty file.
Empty file added tools/summary/__init__.py
Empty file.
15 changes: 15 additions & 0 deletions tools/summary/diff
Original file line number Diff line number Diff line change
@@ -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` <src dir> <dst dir>"
exit
fi

for f in `find $src -maxdepth 1 -name *summary.${format}`; do
diff -y $dst/$f $f| less
done
12 changes: 12 additions & 0 deletions tools/summary/issues-and-bugs
Original file line number Diff line number Diff line change
@@ -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
8 changes: 8 additions & 0 deletions tools/summary/less
Original file line number Diff line number Diff line change
@@ -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
98 changes: 98 additions & 0 deletions tools/summary/view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/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

import yaml
# load all plugins
import hotsos.plugin_extensions # noqa: F401, pylint: disable=W0611
from hotsos.core import plugintools


def get_summary(root):
if root is None:
root = '.'

paths = []
if os.path.isdir(root):
for encoding in ['json', 'yaml']:
results = glob.glob(os.path.join(root, f'*.{encoding}'))
if results:
paths = results
break
else:
paths = [root]

for path in paths:
with open(path, encoding='utf-8') as fd:
if path.endswith('json'):
yield json.loads(fd.read())
else:
yield yaml.safe_load(fd.read())


def get_info(s):
_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'])

return _enabled, _services, _has_bugs, _has_potential_issues


def main():
if len(sys.argv) > 1:
path = sys.argv[1]
else:
path = None

for s in get_summary(path):
subprocess.call(['clear'])
print(f"host: {s['system']['hostname']}")
print(f"date: {s['system']['date']}")
_enabled, _services, _has_bugs, _has_potential_issues = get_info(s)
# print("enabled: {}".format(', '.join(sorted(_enabled))))
print("services:")
for plugin, svcs in _services.items():
_svcs = ', '.join(svcs)
print(f" {plugin}: {_svcs}")

if _has_bugs:
print("bugs:")
for btype, content in _has_bugs.items():
_content = '\n'.join(content)
print(f" {btype}: {_content}\n")

if _has_potential_issues:
print("issues:")
for btype, content in _has_potential_issues.items():
print(f" {btype}:")
for msg in content:
print(f" {msg}")

input("\nNext? [ENTER]")

print("")


if __name__ == "__main__":
main()
9 changes: 7 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ passenv =
TESTS_LOG_LEVEL_DEBUG
TESTS_LOG_TEST_ARTIFACTS
pyfiles =
{toxinidir}/hotsos {[testenv]unit_tests} {toxinidir}/tools/validation
{toxinidir}/hotsos {[testenv]unit_tests} {toxinidir}/tools/validation {toxinidir}/tools/summary
setenv =
HOTSOS_ROOT={toxinidir}/hotsos
PYTHONHASHSEED=0
Expand Down Expand Up @@ -75,7 +75,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}
Expand Down
Loading