feat(recorder): Identify duplicate queries
This commit is contained in:
parent
f83d1be9af
commit
a9238c874d
2 changed files with 40 additions and 5 deletions
|
|
@ -33,6 +33,14 @@
|
|||
<div class="section-body">
|
||||
<div class="form-column col-sm-12">
|
||||
<form>
|
||||
<div class="form-group frappe-control input-max-width" data-fieldtype="Check">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<span class="input-area"><input type="checkbox" class="input-with-feedback bold" data-fieldtype="Check" v-model="group_duplicates"></span>
|
||||
<span class="label-area small">Group Duplicate Queries</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="frappe-control" data-fieldtype="Table">
|
||||
<div>
|
||||
<div class="form-grid">
|
||||
|
|
@ -41,26 +49,32 @@
|
|||
<div class="data-row row">
|
||||
<div class="row-index col col-xs-1">
|
||||
<span>Index</span></div>
|
||||
<div class="col grid-static-col col-xs-8">
|
||||
<div class="col grid-static-col col-xs-6">
|
||||
<div class="static-area ellipsis">Query</div>
|
||||
</div>
|
||||
<div class="col grid-static-col col-xs-2">
|
||||
<div class="static-area ellipsis text-right">Duration (ms)</div>
|
||||
</div>
|
||||
<div class="col grid-static-col col-xs-2">
|
||||
<div class="static-area ellipsis text-right">Exact Copies</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-body">
|
||||
<div class="rows">
|
||||
<div class="grid-row" :class="showing == call.index ? 'grid-row-open' : ''" v-for="call in paginated(sorted(request.calls))" :key="call.index">
|
||||
<div class="grid-row" :class="showing == call.index ? 'grid-row-open' : ''" v-for="call in paginated(sorted(grouped(request.calls)))" :key="call.index">
|
||||
<div class="data-row row" v-if="showing != call.index" style="display: block;" @click="showing = call.index" >
|
||||
<div class="row-index col col-xs-1"><span>{{ call.index }}</span></div>
|
||||
<div class="col grid-static-col col-xs-8" data-fieldtype="Code">
|
||||
<div class="col grid-static-col col-xs-6" data-fieldtype="Code">
|
||||
<div class="static-area"><span>{{ call.query }}</span></div>
|
||||
</div>
|
||||
<div class="col grid-static-col col-xs-2">
|
||||
<div class="static-area ellipsis text-right">{{ call.duration }}</div>
|
||||
</div>
|
||||
<div class="col grid-static-col col-xs-2">
|
||||
<div class="static-area ellipsis text-right">{{ call.exact_copies }}</div>
|
||||
</div>
|
||||
<div class="col col-xs-1"><a class="close btn-open-row">
|
||||
<span class="octicon octicon-triangle-down"></span></a>
|
||||
</div>
|
||||
|
|
@ -94,6 +108,12 @@
|
|||
<div class="control-value like-disabled-input">{{ call.duration }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="frappe-control input-max-width">
|
||||
<div class="form-group">
|
||||
<div class="clearfix"><label class="control-label">Exact Copies</label></div>
|
||||
<div class="control-value like-disabled-input">{{ call.exact_copies }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="frappe-control">
|
||||
<div class="form-group">
|
||||
<div class="clearfix"><label class="control-label">Stack Trace</label></div>
|
||||
|
|
@ -178,6 +198,7 @@ export default {
|
|||
table_columns: [
|
||||
{label: "Execution Order", slug: "index", sortable: true},
|
||||
{label: "Duration (ms)", slug: "duration", sortable: true},
|
||||
{label: "Exact Copies", slug: "exact_copies", sortable: true},
|
||||
],
|
||||
query: {
|
||||
sort: "index",
|
||||
|
|
@ -188,6 +209,7 @@ export default {
|
|||
total: 0,
|
||||
}
|
||||
},
|
||||
group_duplicates: false,
|
||||
showing: null,
|
||||
request: {
|
||||
calls: [],
|
||||
|
|
@ -235,6 +257,13 @@ export default {
|
|||
const sort = this.query.sort;
|
||||
return calls.sort((a,b) => (a[sort] > b[sort]) ? order : -order);
|
||||
},
|
||||
grouped: function(calls) {
|
||||
if(this.group_duplicates) {
|
||||
calls = calls.slice();
|
||||
return calls.uniqBy(call => call["query"]);
|
||||
}
|
||||
return calls
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
frappe.breadcrumbs.add({
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
# MIT License. See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from collections import Counter
|
||||
import datetime
|
||||
import json
|
||||
import re
|
||||
|
|
@ -89,14 +90,19 @@ class Recorder():
|
|||
frappe.cache().hset(RECORDER_REQUEST_SPARSE_HASH, self.uuid, request_data)
|
||||
frappe.publish_realtime(event="recorder-dump-event", message=json.dumps(request_data, default=str))
|
||||
|
||||
for index, call in enumerate(self.calls):
|
||||
call["index"] = index
|
||||
self.mark_duplicates()
|
||||
|
||||
request_data["calls"] = self.calls
|
||||
request_data["headers"] = self.headers
|
||||
request_data["form_dict"] = self.form_dict
|
||||
frappe.cache().hset(RECORDER_REQUEST_HASH, self.uuid, request_data)
|
||||
|
||||
def mark_duplicates(self):
|
||||
counts = Counter([call["query"] for call in self.calls])
|
||||
for index, call in enumerate(self.calls):
|
||||
call["index"] = index
|
||||
call["exact_copies"] = counts[call["query"]]
|
||||
|
||||
|
||||
def _patch():
|
||||
frappe.db._sql = frappe.db.sql
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue