Warning
This document is for an in-development version of Galaxy. You can alternatively view this page in the latest release if it exists or view the top of the latest release's documentation.
Source code for galaxy.webapps.galaxy.api.metrics
"""
API operations for for querying and recording user metrics from some client
(typically a user's browser).
"""
# TODO: facade or adapter to fluentd
import datetime
import logging
from galaxy.web import expose_api_anonymous
from galaxy.webapps.base.controller import BaseAPIController
log = logging.getLogger(__name__)
[docs]class MetricsController(BaseAPIController):
[docs] def __init__(self, app):
super(MetricsController, self).__init__(app)
#: set to true to send additional debugging info to the log
self.debugging = True
def _deserialize_isoformat_date(self, datestring):
"""
Convert ISO formatted date string into python datetime.
"""
return datetime.datetime.strptime(datestring, "%Y-%m-%dT%H:%M:%S.%fZ")
[docs] @expose_api_anonymous
def create(self, trans, payload, **kwd):
"""
create( trans, payload )
* POST /api/metrics:
record any metrics sent and return some status object
.. note:: Anonymous users can post metrics
:type payload: dict
:param payload: (optional) dictionary structure containing:
* metrics: a list containing dictionaries of the form:
** namespace: label indicating the source of the metric
** time: isoformat datetime when the metric was recorded
** level: an integer representing the metric's log level
** args: a json string containing an array of extra data
:rtype: dict
:returns: status object
"""
user_id = trans.user.id if trans.user else None
session_id = trans.galaxy_session.id if trans.galaxy_session else None
parsed_gen = self._parse_metrics(payload.get('metrics', None), user_id, session_id)
self._send_metrics(trans, parsed_gen)
response = self._get_server_pong(trans)
return response
# TODO: move the following to DAO/Manager object
def _parse_metrics(self, metrics, user_id=None, session_id=None):
"""
Return a generator yielding the each given metric as a tuple:
* label: the namespace of the metric
* time: datetime of the metric's creation
* kwargs: a dictionary containing:
** level: the log level of the metric
** user: the user associated with the metric
(will be None if anonymous user)
** session: the session of the current user
"""
metrics = metrics or []
for metric in metrics:
label = metric['namespace']
time = self._deserialize_isoformat_date(metric['time'])
kwargs = {
'level' : metric['level'],
'args' : metric['args'],
'user' : user_id,
'session' : session_id
}
yield (label, time, kwargs)
def _send_metrics(self, trans, metrics):
"""
Send metrics to the app's `trace_logger` if set and
send to `log.debug` if this controller if `self.debugging`.
Precondition: metrics are parsed and in proper format.
"""
if trans.app.trace_logger:
for label, time, kwargs in metrics:
trans.app.trace_logger.log(label, event_time=int(time), **kwargs)
elif self.debugging:
for label, time, kwargs in metrics:
log.debug('%s %s %s', label, time, kwargs)
def _get_server_pong(self, trans):
"""
Return some status message or object.
For future use.
"""
return {}