Project import generated by Copybara.
GitOrigin-RevId: d9e9e3fb4e31372ec1fb43b178994ca78fa8fe70
diff --git a/framework/ts_mon_js.py b/framework/ts_mon_js.py
new file mode 100644
index 0000000..61be1a8
--- /dev/null
+++ b/framework/ts_mon_js.py
@@ -0,0 +1,110 @@
+# 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 google.appengine.api import users
+
+from infra_libs import ts_mon
+
+
+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