Source code for mentat.module.informant
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#-------------------------------------------------------------------------------
# This file is part of Mentat system (https://mentat.cesnet.cz/).
#
# Copyright (C) since 2011 CESNET, z.s.p.o (http://www.ces.net/)
# Use of this source is governed by the MIT license, see LICENSE file.
#-------------------------------------------------------------------------------
"""
This Mentat module is a script providing periodical informational reports about
overall performance of Mentat system.
This script is implemented using the :py:mod:`pyzenkit.zenscript` framework and
so it provides all of its core features. See the documentation for more in-depth
details.
It is further based on :py:mod:`mentat.script.fetcher` module, which provides
database fetching and message post-processing capabilities.
Usage examples
--------------
.. code-block:: shell
# Display help message and exit.
mentat-informant.py --help
# Run in debug mode (enable output of debugging information to terminal).
mentat-informant.py --debug
# Run with increased logging level.
mentat-informant.py --log-level debug
Available script commands
-------------------------
``report`` (*default*)
Generate report containing overall Mentat system performance statistics
within configured time interval thresholds.
"""
__author__ = "Jan Mach <jan.mach@cesnet.cz>"
__credits__ = "Pavel Kácha <pavel.kacha@cesnet.cz>, Andrea Kropáčová <andrea.kropacova@cesnet.cz>"
#
# Custom libraries
#
import mentat.script.fetcher
import mentat.plugin.app.mailer
import mentat.const
import mentat.reports.overview
[docs]class MentatInformantScript(mentat.script.fetcher.FetcherScript):
"""
Implementation of Mentat module (script) providing periodical statistical
overview for message processing performance analysis.
"""
#
# Class constants.
#
# List of configuration keys.
CORECFG_INFORMANT = '__core__informant'
CONFIG_REPORTS_DIR = 'reports_dir'
CONFIG_TEMPLATES_DIR = 'templates_dir'
CONFIG_TEMPLATE_VARS = 'template_vars'
CONFIG_FORCE_TEMPLATE = 'force_template'
CONFIG_FORCE_LOCALE = 'force_locale'
CONFIG_FORCE_TIMEZONE = 'force_timezone'
def __init__(self):
"""
Initialize statistician script object. This method overrides the base
implementation in :py:func:`mentat.script.fetcher.FetcherScript.__init__`
and it aims to even more simplify the script object creation by providing
configuration values for parent contructor.
"""
# Declare private attributes.
self.sqlservice = None
self.mailerservice = None
super().__init__(
description = 'mentat-informant.py - Mentat system overall performance statistics',
#
# Load additional application-level plugins.
#
plugins = [
mentat.plugin.app.mailer.MailerPlugin()
]
)
def _sub_stage_init(self, **kwargs):
"""
**SUBCLASS HOOK**: Perform additional custom initialization actions.
This method is called from the main constructor in :py:func:`pyzenkit.baseapp.BaseApp.__init__`
as a part of the **__init__** stage of application`s life cycle.
:param kwargs: Various additional parameters passed down from constructor.
"""
# Override default 'interval' value.
self.config[self.CONFIG_INTERVAL] = 'daily'
# Override default 'adjust_thresholds' value.
self.config[self.CONFIG_ADJUST_THRESHOLDS] = True
def _init_argparser(self, **kwargs):
"""
Initialize script command line argument parser. This method overrides the
base implementation in :py:func:`pyzenkit.zenscript.ZenScript._init_argparser`
and it must return valid :py:class:`argparse.ArgumentParser` object. It
appends additional command line options custom for this script object.
This method is called from the main constructor in :py:func:`pyzenkit.baseapp.BaseApp.__init__`
as a part of the **__init__** stage of application`s life cycle.
:param kwargs: Various additional parameters passed down from object constructor.
:return: Valid argument parser object.
:rtype: argparse.ArgumentParser
"""
argparser = super()._init_argparser(**kwargs)
#
# Create and populate options group for custom script arguments.
#
arggroup_script = argparser.add_argument_group('custom script arguments')
arggroup_script.add_argument(
'--force-template',
type = str,
default = None,
help = 'force a template for generating reports'
)
arggroup_script.add_argument(
'--force-locale',
type = str,
default = None,
help = 'force a locale for generating reports'
)
arggroup_script.add_argument(
'--force-timezone',
type = str,
default = None,
help = 'force a timezone for generating reports'
)
return argparser
def _init_config(self, cfgs, **kwargs):
"""
Initialize default script configurations. This method overrides the base
implementation in :py:func:`pyzenkit.zenscript.ZenScript._init_config`
and it appends additional configurations via ``cfgs`` parameter.
This method is called from the main constructor in :py:func:`pyzenkit.baseapp.BaseApp.__init__`
as a part of the **__init__** stage of application`s life cycle.
:param list cfgs: Additional set of configurations.
:param kwargs: Various additional parameters passed down from constructor.
:return: Default configuration structure.
:rtype: dict
"""
cfgs = (
(self.CONFIG_FORCE_TEMPLATE, 'default'),
(self.CONFIG_FORCE_LOCALE, 'en'),
(self.CONFIG_FORCE_TIMEZONE, 'UTC'),
(self.CONFIG_TEMPLATE_VARS, {}),
) + cfgs
return super()._init_config(cfgs, **kwargs)
#---------------------------------------------------------------------------
[docs] def get_default_command(self):
"""
Return the name of the default script command. This command will be executed
in case it is not explicitly selected either by command line option, or
by configuration file directive.
:return: Name of the default command.
:rtype: str
"""
return 'report'
[docs] def cbk_command_report(self):
"""
Implementation of the **report** command (*default*).
Calculate statistics for messages stored into database within configured
time interval thresholds.
"""
(time_l, time_h) = self.calculate_interval_thresholds(
time_high = self.c(self.CONFIG_TIME_HIGH),
interval = self.c(self.CONFIG_INTERVAL),
adjust = self.c(self.CONFIG_REGULAR)
)
time_l = time_l.replace(microsecond = 0)
time_h = time_h.replace(microsecond = 0)
self.logger.info("Lower summary report calculation time interval threshold: %s (%s)", time_l.isoformat(), time_l.timestamp())
self.logger.info("Upper summary report calculation time interval threshold: %s (%s)", time_h.isoformat(), time_h.timestamp())
self.logger.info("Using template '%s' to generate informational summary report.", self.c(self.CONFIG_FORCE_TEMPLATE))
reporter = mentat.reports.overview.OverviewReporter(
self.logger,
self.config[self.CORECFG_INFORMANT][self.CONFIG_REPORTS_DIR],
self.config[self.CORECFG_INFORMANT][self.CONFIG_TEMPLATES_DIR],
self.c(self.CONFIG_FORCE_LOCALE),
self.c(self.CONFIG_FORCE_TIMEZONE)
)
result = reporter.report(
time_h,
time_l,
self.sqlservice.session,
self.c(self.CONFIG_FORCE_TEMPLATE),
self.mailerservice,
self.c(self.CONFIG_TEMPLATE_VARS),
)
return result