blob: 0dbb121dd0c783bb89f3fe17460aa98bfc8aa3cb [file] [log] [blame]
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
"""ts_mon JavaScript proxy handler."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from framework import authdata
from framework import sql
from framework import xsrf
from gae_ts_mon.handlers import TSMonJSHandler
from gae_ts_mon.flask_handlers import TSMonJSFlaskHandler
from google.appengine.api import users
from infra_libs import ts_mon
import flask
STANDARD_FIELDS = [
ts_mon.StringField('client_id'),
ts_mon.StringField('host_name'),
ts_mon.BooleanField('document_visible'),
]
# User action metrics.
ISSUE_CREATE_LATENCY_METRIC = ts_mon.CumulativeDistributionMetric(
'monorail/frontend/issue_create_latency', (
'Latency between Issue Entry form submission and page load of '
'the subsequent issue page.'
), field_spec=STANDARD_FIELDS,
units=ts_mon.MetricsDataUnits.MILLISECONDS)
ISSUE_UPDATE_LATENCY_METRIC = ts_mon.CumulativeDistributionMetric(
'monorail/frontend/issue_update_latency', (
'Latency between Issue Update form submission and page load of '
'the subsequent issue page.'
), field_spec=STANDARD_FIELDS,
units=ts_mon.MetricsDataUnits.MILLISECONDS)
AUTOCOMPLETE_POPULATE_LATENCY_METRIC = ts_mon.CumulativeDistributionMetric(
'monorail/frontend/autocomplete_populate_latency', (
'Latency between page load and autocomplete options loading.'
), field_spec=STANDARD_FIELDS,
units=ts_mon.MetricsDataUnits.MILLISECONDS)
CHARTS_SWITCH_DATE_RANGE_METRIC = ts_mon.CounterMetric(
'monorail/frontend/charts/switch_date_range', (
'Number of times user clicks frequency button.'
), field_spec=STANDARD_FIELDS + [ts_mon.IntegerField('date_range')])
# Page load metrics.
ISSUE_COMMENTS_LOAD_EXTRA_FIELDS = [
ts_mon.StringField('template_name'),
ts_mon.BooleanField('full_app_load'),
]
ISSUE_COMMENTS_LOAD_LATENCY_METRIC = ts_mon.CumulativeDistributionMetric(
'monorail/frontend/issue_comments_load_latency', (
'Time from navigation or click to issue comments loaded.'
), field_spec=STANDARD_FIELDS + ISSUE_COMMENTS_LOAD_EXTRA_FIELDS,
units=ts_mon.MetricsDataUnits.MILLISECONDS)
DOM_CONTENT_LOADED_EXTRA_FIELDS = [
ts_mon.StringField('template_name')]
DOM_CONTENT_LOADED_METRIC = ts_mon.CumulativeDistributionMetric(
'frontend/dom_content_loaded', (
'domContentLoaded performance timing.'
), field_spec=STANDARD_FIELDS + DOM_CONTENT_LOADED_EXTRA_FIELDS,
units=ts_mon.MetricsDataUnits.MILLISECONDS)
ISSUE_LIST_LOAD_EXTRA_FIELDS = [
ts_mon.StringField('template_name'),
ts_mon.BooleanField('full_app_load'),
]
ISSUE_LIST_LOAD_LATENCY_METRIC = ts_mon.CumulativeDistributionMetric(
'monorail/frontend/issue_list_load_latency', (
'Time from navigation or click to search issues list loaded.'
), field_spec=STANDARD_FIELDS + ISSUE_LIST_LOAD_EXTRA_FIELDS,
units=ts_mon.MetricsDataUnits.MILLISECONDS)
class MonorailTSMonJSHandler(TSMonJSHandler):
def __init__(self, request=None, response=None):
super(MonorailTSMonJSHandler, self).__init__(request, response)
self.register_metrics([
ISSUE_CREATE_LATENCY_METRIC,
ISSUE_UPDATE_LATENCY_METRIC,
AUTOCOMPLETE_POPULATE_LATENCY_METRIC,
CHARTS_SWITCH_DATE_RANGE_METRIC,
ISSUE_COMMENTS_LOAD_LATENCY_METRIC,
DOM_CONTENT_LOADED_METRIC,
ISSUE_LIST_LOAD_LATENCY_METRIC])
def xsrf_is_valid(self, body):
"""This method expects the body dictionary to include two fields:
`token` and `user_id`.
"""
cnxn = sql.MonorailConnection()
token = body.get('token')
user = users.get_current_user()
email = user.email() if user else None
services = self.app.config.get('services')
auth = authdata.AuthData.FromEmail(cnxn, email, services, autocreate=False)
try:
xsrf.ValidateToken(token, auth.user_id, xsrf.XHR_SERVLET_PATH)
return True
except xsrf.TokenIncorrect:
return False
class FlaskMonorailTSMonJSHandler(TSMonJSFlaskHandler):
def __init__(self, services=None):
super(FlaskMonorailTSMonJSHandler, self).__init__(
flask=flask, services=services)
self.register_metrics(
[
ISSUE_CREATE_LATENCY_METRIC, ISSUE_UPDATE_LATENCY_METRIC,
AUTOCOMPLETE_POPULATE_LATENCY_METRIC,
CHARTS_SWITCH_DATE_RANGE_METRIC, ISSUE_COMMENTS_LOAD_LATENCY_METRIC,
DOM_CONTENT_LOADED_METRIC, ISSUE_LIST_LOAD_LATENCY_METRIC
])
def xsrf_is_valid(self, body):
"""This method expects the body dictionary to include two fields:
`token` and `user_id`.
"""
cnxn = sql.MonorailConnection()
token = body.get('token')
user = users.get_current_user()
email = user.email() if user else None
services = self.service
auth = authdata.AuthData.FromEmail(cnxn, email, services, autocreate=False)
try:
xsrf.ValidateToken(token, auth.user_id, xsrf.XHR_SERVLET_PATH)
return True
except xsrf.TokenIncorrect:
return False
def PostMonorailTSMonJSHandler(self):
return self.post()