blob: 0dbb121dd0c783bb89f3fe17460aa98bfc8aa3cb [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001# Copyright 2018 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style
3# license that can be found in the LICENSE file or at
4# https://developers.google.com/open-source/licenses/bsd
5
6"""ts_mon JavaScript proxy handler."""
7from __future__ import print_function
8from __future__ import division
9from __future__ import absolute_import
10
11from framework import authdata
12from framework import sql
13from framework import xsrf
14
15from gae_ts_mon.handlers import TSMonJSHandler
Adrià Vilanova Martínezde942802022-07-15 14:06:55 +020016from gae_ts_mon.flask_handlers import TSMonJSFlaskHandler
Copybara854996b2021-09-07 19:36:02 +000017
18from google.appengine.api import users
19
20from infra_libs import ts_mon
21
Adrià Vilanova Martínezde942802022-07-15 14:06:55 +020022import flask
Copybara854996b2021-09-07 19:36:02 +000023
24STANDARD_FIELDS = [
25 ts_mon.StringField('client_id'),
26 ts_mon.StringField('host_name'),
27 ts_mon.BooleanField('document_visible'),
28]
29
30
31# User action metrics.
32ISSUE_CREATE_LATENCY_METRIC = ts_mon.CumulativeDistributionMetric(
33 'monorail/frontend/issue_create_latency', (
34 'Latency between Issue Entry form submission and page load of '
35 'the subsequent issue page.'
36 ), field_spec=STANDARD_FIELDS,
37 units=ts_mon.MetricsDataUnits.MILLISECONDS)
38ISSUE_UPDATE_LATENCY_METRIC = ts_mon.CumulativeDistributionMetric(
39 'monorail/frontend/issue_update_latency', (
40 'Latency between Issue Update form submission and page load of '
41 'the subsequent issue page.'
42 ), field_spec=STANDARD_FIELDS,
43 units=ts_mon.MetricsDataUnits.MILLISECONDS)
44AUTOCOMPLETE_POPULATE_LATENCY_METRIC = ts_mon.CumulativeDistributionMetric(
45 'monorail/frontend/autocomplete_populate_latency', (
46 'Latency between page load and autocomplete options loading.'
47 ), field_spec=STANDARD_FIELDS,
48 units=ts_mon.MetricsDataUnits.MILLISECONDS)
49CHARTS_SWITCH_DATE_RANGE_METRIC = ts_mon.CounterMetric(
50 'monorail/frontend/charts/switch_date_range', (
51 'Number of times user clicks frequency button.'
52 ), field_spec=STANDARD_FIELDS + [ts_mon.IntegerField('date_range')])
53
54# Page load metrics.
55ISSUE_COMMENTS_LOAD_EXTRA_FIELDS = [
56 ts_mon.StringField('template_name'),
57 ts_mon.BooleanField('full_app_load'),
58]
59ISSUE_COMMENTS_LOAD_LATENCY_METRIC = ts_mon.CumulativeDistributionMetric(
60 'monorail/frontend/issue_comments_load_latency', (
61 'Time from navigation or click to issue comments loaded.'
62 ), field_spec=STANDARD_FIELDS + ISSUE_COMMENTS_LOAD_EXTRA_FIELDS,
63 units=ts_mon.MetricsDataUnits.MILLISECONDS)
64DOM_CONTENT_LOADED_EXTRA_FIELDS = [
65 ts_mon.StringField('template_name')]
66DOM_CONTENT_LOADED_METRIC = ts_mon.CumulativeDistributionMetric(
67 'frontend/dom_content_loaded', (
68 'domContentLoaded performance timing.'
69 ), field_spec=STANDARD_FIELDS + DOM_CONTENT_LOADED_EXTRA_FIELDS,
70 units=ts_mon.MetricsDataUnits.MILLISECONDS)
71
72
73ISSUE_LIST_LOAD_EXTRA_FIELDS = [
74 ts_mon.StringField('template_name'),
75 ts_mon.BooleanField('full_app_load'),
76]
77ISSUE_LIST_LOAD_LATENCY_METRIC = ts_mon.CumulativeDistributionMetric(
78 'monorail/frontend/issue_list_load_latency', (
79 'Time from navigation or click to search issues list loaded.'
80 ), field_spec=STANDARD_FIELDS + ISSUE_LIST_LOAD_EXTRA_FIELDS,
81 units=ts_mon.MetricsDataUnits.MILLISECONDS)
82
83
84class MonorailTSMonJSHandler(TSMonJSHandler):
85
86 def __init__(self, request=None, response=None):
87 super(MonorailTSMonJSHandler, self).__init__(request, response)
88 self.register_metrics([
89 ISSUE_CREATE_LATENCY_METRIC,
90 ISSUE_UPDATE_LATENCY_METRIC,
91 AUTOCOMPLETE_POPULATE_LATENCY_METRIC,
92 CHARTS_SWITCH_DATE_RANGE_METRIC,
93 ISSUE_COMMENTS_LOAD_LATENCY_METRIC,
94 DOM_CONTENT_LOADED_METRIC,
95 ISSUE_LIST_LOAD_LATENCY_METRIC])
96
97 def xsrf_is_valid(self, body):
98 """This method expects the body dictionary to include two fields:
99 `token` and `user_id`.
100 """
101 cnxn = sql.MonorailConnection()
102 token = body.get('token')
103 user = users.get_current_user()
104 email = user.email() if user else None
105
106 services = self.app.config.get('services')
107 auth = authdata.AuthData.FromEmail(cnxn, email, services, autocreate=False)
108 try:
109 xsrf.ValidateToken(token, auth.user_id, xsrf.XHR_SERVLET_PATH)
110 return True
111 except xsrf.TokenIncorrect:
112 return False
Adrià Vilanova Martínezde942802022-07-15 14:06:55 +0200113
114
115class FlaskMonorailTSMonJSHandler(TSMonJSFlaskHandler):
116
117 def __init__(self, services=None):
118 super(FlaskMonorailTSMonJSHandler, self).__init__(
119 flask=flask, services=services)
120 self.register_metrics(
121 [
122 ISSUE_CREATE_LATENCY_METRIC, ISSUE_UPDATE_LATENCY_METRIC,
123 AUTOCOMPLETE_POPULATE_LATENCY_METRIC,
124 CHARTS_SWITCH_DATE_RANGE_METRIC, ISSUE_COMMENTS_LOAD_LATENCY_METRIC,
125 DOM_CONTENT_LOADED_METRIC, ISSUE_LIST_LOAD_LATENCY_METRIC
126 ])
127
128 def xsrf_is_valid(self, body):
129 """This method expects the body dictionary to include two fields:
130 `token` and `user_id`.
131 """
132 cnxn = sql.MonorailConnection()
133 token = body.get('token')
134 user = users.get_current_user()
135 email = user.email() if user else None
136
137 services = self.service
138 auth = authdata.AuthData.FromEmail(cnxn, email, services, autocreate=False)
139 try:
140 xsrf.ValidateToken(token, auth.user_id, xsrf.XHR_SERVLET_PATH)
141 return True
142 except xsrf.TokenIncorrect:
143 return False
144
145 def PostMonorailTSMonJSHandler(self):
146 return self.post()