class Stats(): """ This class is responsible for creating and updating database entry(document in Elasticsearch DB) There are two usage options: 1. without arguments - as a based class of TestStatsMixin - for saving test statistics 2. with arguments - as a separate object to update an existing document """ def __init__(self, *args, **kwargs): self._test_index = kwargs.get('test_index', None) self._test_id = kwargs.get('test_id', None) self._es_doc_type = "test_stats" self.elasticsearch = ES() self._stats = {} if not self._test_id: super(Stats, self).__init__(*args, **kwargs) def get_doc_id(self): return self._test_id def create(self): self.elasticsearch.create_doc(index=self._test_index, doc_type=self._es_doc_type, doc_id=self._test_id, body=self._stats) def update(self, data): """ Update document :param data: data dictionary """ try: self.elasticsearch.update_doc(index=self._test_index, doc_type=self._es_doc_type, doc_id=self._test_id, body=data) except Exception as ex: # pylint: disable=broad-except LOGGER.error('Failed to update test stats: test_id: %s, error: %s', self._test_id, ex) def exists(self): return self.elasticsearch.exists(index=self._test_index, doc_type=self._es_doc_type, id=self._test_id)
class BaseResultsAnalyzer(): # pylint: disable=too-many-instance-attributes def __init__( self, es_index, es_doc_type, send_email=False, email_recipients=(), # pylint: disable=too-many-arguments email_template_fp="", query_limit=1000, logger=None): self._es = ES() self._conf = self._es._conf # pylint: disable=protected-access self._es_index = es_index self._es_doc_type = es_doc_type self._limit = query_limit self._send_email = send_email self._email_recipients = email_recipients self._email_template_fp = email_template_fp self.log = logger if logger else LOGGER def get_all(self): """ Get all the test results in json format """ return self._es.search(index=self._es_index, size=self._limit) # pylint: disable=unexpected-keyword-arg def get_test_by_id(self, test_id): """ Get test results by test id :param test_id: test id created by performance test :return: test results in json format """ if not self._es.exists( index=self._es_index, doc_type=self._es_doc_type, id=test_id): self.log.error('Test results not found: {}'.format(test_id)) return None return self._es.get(index=self._es_index, doc_type=self._es_doc_type, id=test_id) def _test_version(self, test_doc): if test_doc['_source'].get('versions'): for value in ('scylla-server', 'scylla-enterprise-server'): key = test_doc['_source']['versions'].get(value) if key: return key self.log.error('Scylla version is not found for test %s', test_doc['_id']) return None def render_to_html(self, results, html_file_path=""): """ Render analysis results to html template :param results: results dictionary :param html_file_path: Boolean, whether to save html file on disk :return: html string """ self.log.info("Rendering results to html using '%s' template...", self._email_template_fp) loader = jinja2.FileSystemLoader( os.path.dirname(os.path.abspath(__file__))) print(os.path.dirname(os.path.abspath(__file__))) env = jinja2.Environment(loader=loader, autoescape=True, extensions=['jinja2.ext.loopcontrols']) template = env.get_template(self._email_template_fp) html = template.render(results) self.log.info("Results has been rendered to html") if html_file_path: with open(html_file_path, "w") as html_file: html_file.write(html) self.log.info("HTML report saved to '%s'.", html_file_path) return html def send_email(self, subject, content, html=True, files=()): if self._send_email and self._email_recipients: self.log.debug('Send email to {}'.format(self._email_recipients)) email = Email() email.send(subject, content, html=html, recipients=self._email_recipients, files=files) else: self.log.warning( "Won't send email (send_email: %s, recipients: %s)", self._send_email, self._email_recipients) def gen_kibana_dashboard_url(self, dashboard_path=""): return "%s/%s" % (self._conf.get('kibana_url'), dashboard_path)