From 5118dafc65e4ec39b782fa029ba74919700cb42b Mon Sep 17 00:00:00 2001 From: wanghao Date: Thu, 2 Mar 2017 09:18:44 +0800 Subject: [PATCH] Introduce Guru to Zaqar Guru is a mechanism whereby developers and system administrators can generate a report about the state of a running Zaqar executable. This report is called a *Guru Meditation Report* This mechanism will help developer or operator to fix issues in (production) deployments without stopping Zaqar service. Implements: blueprint introduce-guru-to-zaqar Change-Id: I72885be396be7eb0a9dd8fd564d706a8351b02c6 --- doc/source/devref/gmr.rst | 87 +++++++++++++++++++ doc/source/index.rst | 8 ++ etc/oslo-config-generator/zaqar.conf | 1 + ...roduce-guru-to-zaqar-ac7b51c764503829.yaml | 6 ++ requirements.txt | 1 + zaqar/cmd/server.py | 6 ++ zaqar/transport/wsgi/app.py | 6 ++ zaqar/version.py | 1 + 8 files changed, 116 insertions(+) create mode 100644 doc/source/devref/gmr.rst create mode 100644 releasenotes/notes/introduce-guru-to-zaqar-ac7b51c764503829.yaml diff --git a/doc/source/devref/gmr.rst b/doc/source/devref/gmr.rst new file mode 100644 index 000000000..405a3c7fd --- /dev/null +++ b/doc/source/devref/gmr.rst @@ -0,0 +1,87 @@ +.. + Copyright (c) 2017 OpenStack Foundation + 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. + +======================= +Guru Meditation Reports +======================= + +Zaqar contains a mechanism whereby developers and system administrators can +generate a report about the state of a running Zaqar executable. +This report is called a *Guru Meditation Report* (*GMR* for short). + +Generating a GMR +---------------- + +For wsgi and websocket mode, a *GMR* can be generated by sending the *USR2* +signal to any Zaqar process with support (see below). +The *GMR* will then be outputted standard error for that particular process. + +For example, suppose that ``zaqar-server`` has process id ``8675``, and was +run with ``2>/var/log/zaqar/zaqar-server-err.log``. +Then, ``kill -USR2 8675`` will trigger the Guru Meditation report to be +printed to ``/var/log/zaqar/zaqar-server-err.log``. + +For uwsgi mode, user should add a configuration in Zaqar's conf file:: + + [oslo_reports] + file_event_handler=['The path to a file to watch for changes to trigger ' + 'the reports, instead of signals. Setting this option ' + 'disables the signal trigger for the reports.'] + file_event_handler_interval=['How many seconds to wait between polls when ' + 'file_event_handler is set, default value ' + 'is 1'] + +For example, you can specify "file_event_handler=/tmp/guru_report" and +"file_event_handler_interval=1" in Zaqar's conf file. + +A *GMR* can be generated by "touch"ing the file which was specified in +file_event_handler. The *GMR* will then output to standard error for +that particular process. + +For example, suppose that ``zaqar-server`` was run with +``2>/var/log/zaqar/zaqar-server-err.log``, and the file path is +``/tmp/guru_report``. +Then, ``touch /tmp/guru_report`` will trigger the Guru Meditation report to be +printed to ``/var/log/zaqar/zaqar-server-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 + +Extending the GMR +----------------- + +As mentioned above, additional sections can be added to the GMR for a +particular executable. For more information, see the inline documentation +about oslo.reports: +`oslo.reports `_ diff --git a/doc/source/index.rst b/doc/source/index.rst index 00fcafb5d..5bed22b7f 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -208,6 +208,14 @@ Internal API reference api/autoindex +Guru Meditation Reports +======================= + +.. toctree:: + :maxdepth: 1 + + devref/gmr + Indices and tables ------------------ diff --git a/etc/oslo-config-generator/zaqar.conf b/etc/oslo-config-generator/zaqar.conf index 64561e1c8..665fec25b 100644 --- a/etc/oslo-config-generator/zaqar.conf +++ b/etc/oslo-config-generator/zaqar.conf @@ -16,3 +16,4 @@ namespace = keystonemiddleware.auth_token namespace = oslo.cache namespace = oslo.messaging namespace = osprofiler +namespace = oslo.reports diff --git a/releasenotes/notes/introduce-guru-to-zaqar-ac7b51c764503829.yaml b/releasenotes/notes/introduce-guru-to-zaqar-ac7b51c764503829.yaml new file mode 100644 index 000000000..3ffd681e1 --- /dev/null +++ b/releasenotes/notes/introduce-guru-to-zaqar-ac7b51c764503829.yaml @@ -0,0 +1,6 @@ +--- +features: + - Introduce Guru to Zaqar. Guru is a mechanism whereby developers and system + administrators can generate a report about the state of a running Zaqar + executable. This report is called a *Guru Meditation Report*. Now Guru can + support wsgi, websocket and uwsgi modes all. diff --git a/requirements.txt b/requirements.txt index 8cfd5fed4..53298849c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,6 +20,7 @@ oslo.context>=2.12.0 # Apache-2.0 oslo.i18n>=2.1.0 # Apache-2.0 oslo.log>=3.11.0 # Apache-2.0 oslo.messaging>=5.14.0 # Apache-2.0 +oslo.reports>=0.6.0 # Apache-2.0 oslo.serialization>=1.10.0 # Apache-2.0 oslo.utils>=3.18.0 # Apache-2.0 oslo.policy>=1.17.0 # Apache-2.0 diff --git a/zaqar/cmd/server.py b/zaqar/cmd/server.py index 24de42b4d..ae1673f34 100644 --- a/zaqar/cmd/server.py +++ b/zaqar/cmd/server.py @@ -16,10 +16,13 @@ import os from oslo_config import cfg from oslo_log import log +from oslo_reports import guru_meditation_report as gmr +from oslo_reports import opts as gmr_opts from zaqar import bootstrap from zaqar.common import cli from zaqar.common import configs +from zaqar import version # NOTE(eggmaster): define command line options for zaqar-server _CLI_OPTIONS = ( @@ -33,6 +36,7 @@ _CLI_OPTIONS = ( def run(): # Use the global CONF instance conf = cfg.CONF + gmr_opts.set_defaults(conf) # NOTE(eggmaster): register command line options for zaqar-server conf.register_cli_opts(_CLI_OPTIONS) log.register_options(conf) @@ -46,6 +50,8 @@ def run(): conf(project='zaqar', prog='zaqar-server') log.setup(conf, 'zaqar') + gmr.TextGuruMeditation.setup_autorun(version, conf=conf) + server = bootstrap.Bootstrap(conf) # The following code is to daemonize zaqar-server to avoid diff --git a/zaqar/transport/wsgi/app.py b/zaqar/transport/wsgi/app.py index 6c3098a53..ff4909114 100644 --- a/zaqar/transport/wsgi/app.py +++ b/zaqar/transport/wsgi/app.py @@ -28,15 +28,21 @@ to the WSGI app when it is called from other apps. from oslo_config import cfg from oslo_log import log +from oslo_reports import guru_meditation_report as gmr +from oslo_reports import opts as gmr_opts from zaqar import bootstrap +from zaqar import version # Use the global CONF instance conf = cfg.CONF +gmr_opts.set_defaults(conf) log.register_options(conf) conf(project='zaqar', prog='zaqar-queues', args=[]) log.setup(conf, 'zaqar') +gmr.TextGuruMeditation.setup_autorun(version, conf=conf) + boot = bootstrap.Bootstrap(conf) conf.drivers.transport = 'wsgi' application = boot.transport.app diff --git a/zaqar/version.py b/zaqar/version.py index cfd53a648..352b2f228 100644 --- a/zaqar/version.py +++ b/zaqar/version.py @@ -17,6 +17,7 @@ import pbr.version version_info = pbr.version.VersionInfo('zaqar') +version_string = version_info.version_string def verify_sha(expected):