From 5056d2fa90f3d1a02c4d43bf3e5c2464d749b2c2 Mon Sep 17 00:00:00 2001 From: Arik Fraimovich Date: Mon, 12 Jun 2017 11:35:05 +0300 Subject: [PATCH 1/2] Fix: table name wasn't found for count queries. --- redash/handlers/base.py | 5 ++--- redash/metrics/database.py | 33 +++++++++++++++++++++++---------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/redash/handlers/base.py b/redash/handlers/base.py index 6c24f3bab..c5917c923 100644 --- a/redash/handlers/base.py +++ b/redash/handlers/base.py @@ -1,16 +1,15 @@ import time from flask import Blueprint, current_app, request + from flask_login import current_user, login_required from flask_restful import Resource, abort - -from sqlalchemy.orm.exc import NoResultFound - from redash import settings from redash.authentication import current_org from redash.models import ApiUser from redash.tasks import record_event as record_event_task from redash.utils import json_dumps +from sqlalchemy.orm.exc import NoResultFound routes = Blueprint('redash', __name__, template_folder=settings.fix_assets_path('templates')) diff --git a/redash/metrics/database.py b/redash/metrics/database.py index 405873a8c..6ab1f4cb3 100644 --- a/redash/metrics/database.py +++ b/redash/metrics/database.py @@ -1,17 +1,29 @@ -import time import logging +import time -from sqlalchemy.engine import Engine -from sqlalchemy.orm.util import _ORMJoin -from sqlalchemy.event import listens_for - -from flask import has_request_context, g +from flask import g, has_request_context from redash import statsd_client +from sqlalchemy.engine import Engine +from sqlalchemy.event import listens_for +from sqlalchemy.orm.util import _ORMJoin +from sqlalchemy.sql.selectable import Alias metrics_logger = logging.getLogger("metrics") +def _table_name_from_select_element(elt): + t = elt.froms[0] + + if isinstance(t, Alias): + t = t.original.froms[0] + + while isinstance(t, _ORMJoin): + t = t.left + + return t.name + + @listens_for(Engine, "before_execute") def before_execute(conn, elt, multiparams, params): conn.info.setdefault('query_start_time', []).append(time.time()) @@ -23,10 +35,11 @@ def after_execute(conn, elt, multiparams, params, result): action = elt.__class__.__name__ if action == 'Select': - t = elt.froms[0] - while isinstance(t, _ORMJoin): - t = t.left - name = t.name + name = 'unknown' + try: + name = _table_name_from_select_element(elt) + except Exception: + logging.exception('Failed finding table name.') elif action in ['Update', 'Insert', 'Delete']: name = elt.table.name else: From 7d5d7c4a6b6c609ed925f48bfebd114dbdf152dc Mon Sep 17 00:00:00 2001 From: Arik Fraimovich Date: Mon, 12 Jun 2017 11:35:44 +0300 Subject: [PATCH 2/2] Change: report endpoints without dots for metrics --- redash/metrics/request.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/redash/metrics/request.py b/redash/metrics/request.py index aa667c35b..480625ac4 100644 --- a/redash/metrics/request.py +++ b/redash/metrics/request.py @@ -3,6 +3,7 @@ import time from collections import namedtuple from flask import g, request + from redash import statsd_client metrics_logger = logging.getLogger("metrics") @@ -19,19 +20,20 @@ def calculate_metrics(response): request_duration = (time.time() - g.start_time) * 1000 queries_duration = g.get('queries_duration', 0.0) queries_count = g.get('queries_count', 0.0) + endpoint = (request.endpoint or 'unknown').replace('.', '_') metrics_logger.info("method=%s path=%s endpoint=%s status=%d content_type=%s content_length=%d duration=%.2f query_count=%d query_duration=%.2f", request.method, request.path, - request.endpoint, + endpoint, response.status_code, response.content_type, - response.content_length, + response.content_length or -1, request_duration, queries_count, queries_duration) - statsd_client.timing('requests.{}.{}'.format(request.endpoint, request.method.lower()), request_duration) + statsd_client.timing('requests.{}.{}'.format(endpoint, request.method.lower()), request_duration) return response