2017-02-20 02:11:06 +00:00
|
|
|
import json
|
2017-02-20 12:52:19 +00:00
|
|
|
import logging
|
2017-02-20 02:43:16 +00:00
|
|
|
import pkg_resources
|
2017-02-20 02:11:06 +00:00
|
|
|
|
2017-02-20 12:48:22 +00:00
|
|
|
from tornado import web
|
2017-02-20 02:11:06 +00:00
|
|
|
|
|
|
|
|
2017-02-20 12:52:19 +00:00
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
2017-02-20 02:11:06 +00:00
|
|
|
class StatusHandler(web.RequestHandler):
|
|
|
|
"""
|
|
|
|
Simple handler that returns application status information.
|
2017-02-20 02:43:16 +00:00
|
|
|
|
|
|
|
The easiest way to use this handler is to pass your package's
|
|
|
|
name as the ``package`` kwarg to :class:`tornado.web.URLSpec`::
|
|
|
|
|
|
|
|
app = web.Application([
|
|
|
|
web.url('/status', StatusHandler, {'package': 'my-package'}),
|
|
|
|
])
|
|
|
|
|
|
|
|
If your application is not bundled as a python package, then you can
|
|
|
|
specify the name and version explicitly::
|
|
|
|
|
|
|
|
app = web.Application([
|
|
|
|
web.url('/status', StatusHandler,
|
|
|
|
{'name': 'my-package', 'version': '0.0.1'}),
|
|
|
|
])
|
|
|
|
|
2017-02-20 02:11:06 +00:00
|
|
|
"""
|
|
|
|
|
2017-02-20 12:48:22 +00:00
|
|
|
OK = 'ok'
|
|
|
|
FAILURE = 'failed'
|
|
|
|
|
|
|
|
_package_name = None
|
|
|
|
_application_name = 'UNKNOWN'
|
|
|
|
_application_version = None
|
|
|
|
|
|
|
|
@property
|
|
|
|
def application_name(self):
|
|
|
|
"""The application's reported name."""
|
|
|
|
self._lookup_package_info()
|
|
|
|
return self._application_name
|
|
|
|
|
|
|
|
@property
|
|
|
|
def application_version(self):
|
|
|
|
"""The application's version number."""
|
|
|
|
self._lookup_package_info()
|
|
|
|
return self._application_version
|
|
|
|
|
|
|
|
@property
|
|
|
|
def application_status(self):
|
|
|
|
"""The application's current status."""
|
|
|
|
self._lookup_package_info()
|
|
|
|
if self.application_name is None:
|
|
|
|
return self.FAILURE
|
|
|
|
return self.OK
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def _lookup_package_info(cls):
|
|
|
|
if cls._package_name is not None:
|
|
|
|
try:
|
|
|
|
pkg_info = pkg_resources.get_distribution(cls._package_name)
|
|
|
|
cls._application_name = pkg_info.project_name
|
|
|
|
cls._application_version = pkg_info.version
|
|
|
|
cls._package_name = None
|
2017-02-20 12:52:19 +00:00
|
|
|
_LOGGER.debug('found application information "%s" %s',
|
|
|
|
cls._application_name, cls._application_version)
|
2017-02-20 12:48:22 +00:00
|
|
|
except pkg_resources.ResolutionError:
|
2017-02-20 12:52:19 +00:00
|
|
|
_LOGGER.exception('failed to lookup package "%r"',
|
|
|
|
cls._package_name)
|
2017-02-20 12:48:22 +00:00
|
|
|
cls._application_name = None
|
|
|
|
cls._application_version = None
|
2017-02-20 02:11:06 +00:00
|
|
|
|
2017-02-20 02:43:16 +00:00
|
|
|
def initialize(self, **kwargs):
|
2017-02-20 02:11:06 +00:00
|
|
|
"""
|
|
|
|
Sets the static information.
|
|
|
|
|
2017-02-20 02:43:16 +00:00
|
|
|
:keyword str package: name of the package to retrieve
|
|
|
|
metadata from
|
|
|
|
:keyword str name: name of the application
|
|
|
|
:keyword str version: application version number
|
|
|
|
|
|
|
|
If the ``package`` keyword is specified, then the distribution
|
|
|
|
is retrieved using :py:mod:`pkg_resources` and used as a source
|
|
|
|
of status information. Otherwise, the ``name`` and ``version``
|
|
|
|
keywords are used.
|
2017-02-20 02:11:06 +00:00
|
|
|
|
|
|
|
"""
|
2017-02-20 12:48:22 +00:00
|
|
|
cls = self.__class__
|
2017-02-20 02:43:16 +00:00
|
|
|
if 'package' in kwargs:
|
2017-02-20 12:48:22 +00:00
|
|
|
cls._package_name = kwargs['package']
|
2017-02-20 02:43:16 +00:00
|
|
|
else:
|
2017-02-20 12:48:22 +00:00
|
|
|
cls._application_name = kwargs['name']
|
|
|
|
cls._application_version = kwargs['version']
|
2017-02-20 02:11:06 +00:00
|
|
|
|
|
|
|
def get(self):
|
|
|
|
"""
|
|
|
|
Returns a JSON object containing the application status.
|
|
|
|
|
|
|
|
**Sample Response**
|
|
|
|
|
|
|
|
.. code-block:: json
|
|
|
|
|
|
|
|
{
|
|
|
|
"name": "application-name",
|
|
|
|
"version": "1.2.3",
|
|
|
|
"status": "ok"
|
|
|
|
}
|
|
|
|
|
|
|
|
"""
|
2017-02-20 12:48:22 +00:00
|
|
|
if self.application_status == self.FAILURE:
|
|
|
|
self.set_status(500)
|
|
|
|
else:
|
|
|
|
self.set_status(200)
|
|
|
|
|
2017-02-20 02:11:06 +00:00
|
|
|
self.set_header('Content-Type', 'application/json')
|
2017-02-20 12:48:22 +00:00
|
|
|
self.write(json.dumps({
|
|
|
|
'name': self.application_name,
|
|
|
|
'version': self.application_version,
|
|
|
|
'status': self.application_status
|
|
|
|
}).encode('utf-8'))
|
2017-02-20 02:11:06 +00:00
|
|
|
self.finish()
|