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 {}