From 1e49aad113096c8bf694769aa945d0769e4d8637 Mon Sep 17 00:00:00 2001 From: "zhangchunlong1@huawei.com" Date: Tue, 19 May 2015 17:18:23 +0800 Subject: [PATCH] Introduce Guru Meditation Reports into Heat This commit integrates functionality from the `openstack.common.report` module into Heat. This enables Heat services to receive SIGUSR1 and print a Guru Meditation Report to stderr or file. The required modules were added to 'openstack-common.conf' as well. Change-Id: I36af98590e5556f012b0e9f79e21585e216b7280 Blueprint: guru-meditation-report Co-Authored-By: huangtianhua --- bin/heat-api | 6 ++-- bin/heat-api-cfn | 2 ++ bin/heat-api-cloudwatch | 2 ++ bin/heat-engine | 6 ++-- doc/source/gmr.rst | 73 +++++++++++++++++++++++++++++++++++++++++ doc/source/index.rst | 1 + requirements.txt | 1 + 7 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 doc/source/gmr.rst diff --git a/bin/heat-api b/bin/heat-api index 8ac4ab73da..a1872d984b 100755 --- a/bin/heat-api +++ b/bin/heat-api @@ -33,6 +33,7 @@ if os.path.exists(os.path.join(possible_topdir, 'heat', '__init__.py')): from oslo_config import cfg import oslo_i18n as i18n from oslo_log import log as logging +from oslo_reports import guru_meditation_report as gmr from oslo_service import systemd import six @@ -50,8 +51,8 @@ LOG = logging.getLogger('heat.api') if __name__ == '__main__': try: logging.register_options(cfg.CONF) - version = version.version_info.version_string() - cfg.CONF(project='heat', prog='heat-api', version=version) + cfg.CONF(project='heat', prog='heat-api', + version=version.version_info.version_string()) logging.setup(cfg.CONF, 'heat-api') messaging.setup() @@ -62,6 +63,7 @@ if __name__ == '__main__': LOG.info(_LI('Starting Heat ReST API on %(host)s:%(port)s'), {'host': host, 'port': port}) profiler.setup('heat-api', host) + gmr.TextGuruMeditation.setup_autorun(version) server = wsgi.Server() server.start(app, cfg.CONF.heat_api, default_port=port) systemd.notify_once() diff --git a/bin/heat-api-cfn b/bin/heat-api-cfn index 7fb577d138..8c000d3727 100755 --- a/bin/heat-api-cfn +++ b/bin/heat-api-cfn @@ -35,6 +35,7 @@ if os.path.exists(os.path.join(possible_topdir, 'heat', '__init__.py')): from oslo_config import cfg import oslo_i18n as i18n from oslo_log import log as logging +from oslo_reports import guru_meditation_report as gmr from oslo_service import systemd import six @@ -66,6 +67,7 @@ if __name__ == '__main__': LOG.info(_LI('Starting Heat API on %(host)s:%(port)s'), {'host': host, 'port': port}) profiler.setup('heat-api-cfn', host) + gmr.TextGuruMeditation.setup_autorun(version) server = wsgi.Server() server.start(app, cfg.CONF.heat_api_cfn, default_port=port) systemd.notify_once() diff --git a/bin/heat-api-cloudwatch b/bin/heat-api-cloudwatch index b7850214e2..634ad1d339 100755 --- a/bin/heat-api-cloudwatch +++ b/bin/heat-api-cloudwatch @@ -35,6 +35,7 @@ if os.path.exists(os.path.join(possible_topdir, 'heat', '__init__.py')): from oslo_config import cfg import oslo_i18n as i18n from oslo_log import log as logging +from oslo_reports import guru_meditation_report as gmr from oslo_service import systemd import six @@ -66,6 +67,7 @@ if __name__ == '__main__': LOG.info(_LI('Starting Heat CloudWatch API on %(host)s:%(port)s'), {'host': host, 'port': port}) profiler.setup('heat-api-cloudwatch', host) + gmr.TextGuruMeditation.setup_autorun(version) server = wsgi.Server() server.start(app, cfg.CONF.heat_api_cloudwatch, default_port=port) systemd.notify_once() diff --git a/bin/heat-engine b/bin/heat-engine index cf3b1c4176..315df217cd 100755 --- a/bin/heat-engine +++ b/bin/heat-engine @@ -35,6 +35,7 @@ if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'heat', '__init__.py')): from oslo_config import cfg import oslo_i18n as i18n from oslo_log import log as logging +from oslo_reports import guru_meditation_report as gmr from oslo_service import service from heat.common import config @@ -51,8 +52,8 @@ LOG = logging.getLogger('heat.engine') if __name__ == '__main__': logging.register_options(cfg.CONF) - version = version.version_info.version_string() - cfg.CONF(project='heat', prog='heat-engine', version=version) + cfg.CONF(project='heat', prog='heat-engine', + version=version.version_info.version_string()) logging.setup(cfg.CONF, 'heat-engine') logging.set_defaults() messaging.setup() @@ -70,6 +71,7 @@ if __name__ == '__main__': from heat.engine import service as engine # noqa profiler.setup('heat-engine', cfg.CONF.host) + gmr.TextGuruMeditation.setup_autorun(version) srv = engine.EngineService(cfg.CONF.host, rpc_api.ENGINE_TOPIC) launcher = service.launch(cfg.CONF, srv, workers=cfg.CONF.num_engine_workers) diff --git a/doc/source/gmr.rst b/doc/source/gmr.rst new file mode 100644 index 0000000000..d2b164552f --- /dev/null +++ b/doc/source/gmr.rst @@ -0,0 +1,73 @@ +.. + Copyright (c) 2014 OpenStack Foundation + + 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. + +Guru Meditation Reports +======================= + +Heat contains a mechanism whereby developers and system administrators can generate a report about the state of a running Heat executable. This report is called a *Guru Meditation Report* (*GMR* for short). + +Generating a GMR +---------------- + +A *GMR* can be generated by sending the *USR1* signal to any Heat process with support (see below). The *GMR* will then be outputted standard error for that particular process. + +For example, suppose that ``heat-api`` has process id ``10172``, and was run with ``2>/var/log/heat/heat-api-err.log``. Then, ``kill -USR1 10172`` will trigger the Guru Meditation report to be printed to ``/var/log/heat/heat-api-err.log``. + +Structure of a GMR +------------------ + +The *GMR* is designed to be extensible; any particular executable may add its own sections. However, the base *GMR* consists of several sections: + +Package + Shows information about the package to which this process belongs, including version information + +Threads + Shows stack traces and thread ids for each of the threads within this process + +Green Threads + Shows stack traces for each of the green threads within this process (green threads don't have thread ids) + +Configuration + Lists all the configuration options currently accessible via the CONF object for the current process + +Adding support for GMRs to new executable +------------------------------------------ + +Adding support for a *GMR* to a given executable is fairly easy. + +First import the module (currently residing in oslo-incubator), as well as the Heat version module: + +.. code-block:: python + + from oslo_reports import guru_meditation_report as gmr + from heat import version + +Then, register any additional sections (optional): + +.. code-block:: python + + TextGuruMeditation.register_section('Some Special Section', + some_section_generator) + +Finally (under main), before running the "main loop" of the executable (usually ``server.start()`` or something similar), register the *GMR* hook: + +.. code-block:: python + + TextGuruMeditation.setup_autorun(version) + +Extending the GMR +----------------- + +As mentioned above, additional sections can be added to the GMR for a particular executable. For more information, see the documentation about oslo.reports: `oslo.reports `_ diff --git a/doc/source/index.rst b/doc/source/index.rst index f525aa50bf..5073e0ffbb 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -54,6 +54,7 @@ Developers Documentation architecture pluginguide schedulerhints + gmr API Documentation ======================== diff --git a/requirements.txt b/requirements.txt index fb4e17f40e..f3d3748b22 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,6 +22,7 @@ oslo.log>=1.2.0 # Apache-2.0 oslo.messaging!=1.12.0,>=1.8.0 # Apache-2.0 oslo.middleware!=2.0.0,>=1.2.0 # Apache-2.0 oslo.policy>=0.5.0 # Apache-2.0 +oslo.reports>=0.1.0 # Apache-2.0 oslo.serialization>=1.4.0 # Apache-2.0 oslo.service>=0.1.0 # Apache-2.0 oslo.utils>=1.6.0 # Apache-2.0