Andreas Jaeger 117544f62b Update hacking for Python3
The repo is Python 3 now, so update hacking to version 3.0 which
supports Python 3.

Fix problems found.

Update local hacking checks for new flake8. Note that the repo has been
running hacking 2 for some time due to uncapped setup, and thus fixes
are needed for N350 - the uncapped setup disabled the local hacking
rules. They are now enabled again.

Change-Id: I25e5201933f65ba4d3045e6445f0e6419ea57f3e
2020-04-02 10:05:36 +02:00

144 lines
5.1 KiB
Python

# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
import os
from rally.common import cfg
from rally.common import logging
from rally.common import opts
from rally.common.plugin import plugin
from rally.task.processing import charts
OPTS = {
"openstack": [
cfg.StrOpt(
"osprofiler_chart_mode",
default=None,
help="Mode of embedding OSProfiler's chart. Can be 'text' "
"(embed only trace id), 'raw' (embed raw osprofiler's native "
"report) or a path to directory (raw osprofiler's native "
"reports for each iteration will be saved separately there "
"to decrease the size of rally report itself)")
]
}
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
def _datetime_json_serialize(obj):
if hasattr(obj, "isoformat"):
return obj.isoformat()
else:
return obj
@plugin.configure(name="OSProfiler")
class OSProfilerChart(charts.OutputEmbeddedChart,
charts.OutputEmbeddedExternalChart,
charts.OutputTextArea):
"""Chart for embedding OSProfiler data."""
@classmethod
def _fetch_osprofiler_data(cls, connection_str, trace_id):
from osprofiler.drivers import base
from osprofiler import opts as osprofiler_opts
opts.register_opts(osprofiler_opts.list_opts()) # noqa
try: # noqa
engine = base.get_driver(connection_str)
except Exception:
msg = "Error while fetching OSProfiler results."
if logging.is_debug():
LOG.exception(msg)
else:
LOG.error(msg)
return None
return engine.get_report(trace_id)
@classmethod
def _generate_osprofiler_report(cls, osp_data):
from osprofiler import cmd
path = "%s/template.html" % os.path.dirname(cmd.__file__)
with open(path) as f:
html_obj = f.read()
osp_data = json.dumps(osp_data,
indent=4,
separators=(",", ": "),
default=_datetime_json_serialize)
return html_obj.replace("$DATA", osp_data).replace("$LOCAL", "false")
@classmethod
def _return_raw_response_for_complete_data(cls, data):
return charts.OutputTextArea.render_complete_data({
"title": data["title"],
"widget": "TextArea",
"data": [data["data"]["trace_id"]]
})
@classmethod
def render_complete_data(cls, data):
mode = CONF.openstack.osprofiler_chart_mode
if isinstance(data["data"]["trace_id"], list):
# NOTE(andreykurilin): it is an adoption for the format that we
# used before rally-openstack 1.5.0 .
data["data"]["trace_id"] = data["data"]["trace_id"][0]
if data["data"].get("conn_str") and mode != "text":
osp_data = cls._fetch_osprofiler_data(
data["data"]["conn_str"],
trace_id=data["data"]["trace_id"]
)
if not osp_data:
# for some reasons we failed to fetch data from OSProfiler's
# backend. in this case we can display just trace ID
return cls._return_raw_response_for_complete_data(data)
osp_report = cls._generate_osprofiler_report(osp_data)
title = "{0} : {1}".format(data["title"],
data["data"]["trace_id"])
if (mode and mode != "raw") and "workload_uuid" in data["data"]:
# NOTE(andreykurilin): we need to rework our charts plugin
# mechanism so it is available out of box
workload_uuid = data["data"]["workload_uuid"]
iteration = data["data"]["iteration"]
file_name = "w_%s-%s.html" % (workload_uuid, iteration)
path = os.path.join(mode, file_name)
with open(path, "w") as f:
f.write(osp_report)
return charts.OutputEmbeddedExternalChart.render_complete_data(
{
"title": title,
"widget": "EmbeddedChart",
"data": path
}
)
else:
return charts.OutputEmbeddedChart.render_complete_data(
{"title": title,
"widget": "EmbeddedChart",
"data": osp_report}
)
return cls._return_raw_response_for_complete_data(data)