@@ -10,6 +10,7 @@ import (
1010 "quesma/elasticsearch"
1111 "quesma/jsondiff"
1212 "quesma/logger"
13+ "quesma/quesma/config"
1314 "quesma/quesma/ui/internal/builder"
1415 "strings"
1516 "time"
@@ -75,7 +76,6 @@ If the performance gain is positive, it means that the second backend connector
7576 buffer .Html (`<select id="order_by" name="order_by">` )
7677 buffer .Html (`<option value="default">Default</option>` )
7778 buffer .Html (`<option value="response_similarity">Response similarity</option>` )
78- buffer .Html (`<option value="performance_gain">Performance gain</option>` )
7979 buffer .Html (`<option value="count">Count</option>` )
8080 buffer .Html (`</select>` )
8181 buffer .Html (`<br>` )
@@ -86,7 +86,7 @@ If the performance gain is positive, it means that the second backend connector
8686 buffer .Html (`<div class="menu">` )
8787 buffer .Html ("\n </div>" )
8888 } else {
89- buffer .Html (`<p>A/B Testing results are not available.</p>` )
89+ buffer .Html (`<p>CR results are not available.</p>` )
9090 }
9191
9292 buffer .Html ("\n </main>\n \n " )
@@ -258,17 +258,19 @@ func formatJSON(in *string) string {
258258}
259259
260260type abTestingReportRow struct {
261- dashboardId string
262- panelId string
263- dashboardUrl string
264- detailsUrl string
265- dashboardName string
266- panelName string
267- aName string
268- bName string
269- successRate * float64
270- performanceGain * float64
271- count int
261+ dashboardId string
262+ panelId string
263+ dashboardUrl string
264+ detailsUrl string
265+ dashboardName string
266+ panelName string
267+ aName string
268+ bName string
269+ aTime * float64
270+ bTime * float64
271+ successRate * float64
272+ responseTimeDelta * float64
273+ count int
272274}
273275
274276func (qmc * QuesmaManagementConsole ) abTestingReadReport (kibanaUrl , orderBy string ) ([]abTestingReportRow , error ) {
@@ -281,7 +283,6 @@ func (qmc *QuesmaManagementConsole) abTestingReadReport(kibanaUrl, orderBy strin
281283 orderByToSQL := map [string ]string {
282284 "default" : "dashboard_id, panel_id, a_name, b_name" ,
283285 "response_similarity" : "response_similarity DESC, dashboard_id, panel_id, a_name, b_name" ,
284- "performance_gain" : "performance_gain DESC,dashboard_id, panel_id, a_name, b_name" ,
285286 "count" : "count DESC,dashboard_id, panel_id, a_name, b_name" ,
286287 }
287288
@@ -311,8 +312,10 @@ SELECT
311312 a_name,
312313 b_name,
313314 (sumIf(c,ok)/ sum(c)) * 100 as response_similarity,
314- ((avgIf(a_time,ok)- avgIf(b_time,ok))/avgIf(a_time,ok))*100.0 as performance_gain,
315- sum(c) as count
315+
316+ sum(c) as count,
317+ avgIf(a_time,ok) as a_time,
318+ avgIf(b_time,ok) as b_time
316319FROM
317320 subresults
318321GROUP BY
@@ -331,7 +334,7 @@ GROUP BY
331334
332335 for rows .Next () {
333336 row := abTestingReportRow {}
334- err := rows .Scan (& row .dashboardId , & row .panelId , & row .aName , & row .bName , & row .successRate , & row .performanceGain , & row .count )
337+ err := rows .Scan (& row .dashboardId , & row .panelId , & row .aName , & row .bName , & row .successRate , & row .count , & row .aTime , & row . bTime )
335338 if err != nil {
336339 return nil , err
337340 }
@@ -341,6 +344,26 @@ GROUP BY
341344 row .dashboardName = kibanaDashboards .dashboardName (row .dashboardId )
342345 row .panelName = kibanaDashboards .panelName (row .dashboardId , row .panelId )
343346
347+ if row .aTime != nil && row .bTime != nil {
348+
349+ var clickhouseTime , elasticTime float64
350+
351+ if row .aName == config .ElasticsearchTarget {
352+ elasticTime = * row .aTime
353+ clickhouseTime = * row .bTime
354+ } else {
355+ elasticTime = * row .bTime
356+ clickhouseTime = * row .aTime
357+ }
358+
359+ if elasticTime == 0 {
360+ row .responseTimeDelta = nil
361+ } else {
362+ delta := (elasticTime - clickhouseTime ) / elasticTime * 100
363+ row .responseTimeDelta = & delta
364+ }
365+ }
366+
344367 result = append (result , row )
345368 }
346369
@@ -361,7 +384,7 @@ func (qmc *QuesmaManagementConsole) generateABTestingReport(kibanaUrl, orderBy s
361384 buffer .Html (`<th class="key">Panel</th>` + "\n " )
362385 buffer .Html (`<th class="key">Count <br> <small>(since start)</small></th>` + "\n " )
363386 buffer .Html (`<th class="key">Response similarity</th>` + "\n " )
364- buffer .Html (`<th class="key">Performance gain </th>` + "\n " )
387+ buffer .Html (`<th class="key">Response time delta </th>` + "\n " )
365388 buffer .Html (`<th class="key"></th>` + "\n " )
366389 buffer .Html ("</tr>\n " )
367390 buffer .Html ("</thead>\n " )
@@ -405,8 +428,36 @@ func (qmc *QuesmaManagementConsole) generateABTestingReport(kibanaUrl, orderBy s
405428 buffer .Html (`</td>` )
406429
407430 buffer .Html (`<td>` )
408- if row .performanceGain != nil {
409- buffer .Text (fmt .Sprintf ("%.01f%%" , * row .performanceGain ))
431+
432+ const minTime = 0.05 // 50ms, we don't show performance gain for queries faster than this
433+ const maxTime = 5.0 // if a query takes longer than this, we show the name of the slowest backend
434+
435+ if row .responseTimeDelta != nil {
436+ buffer .Html (`<span title="` )
437+ buffer .Html (fmt .Sprintf ("%s=%.03fs, %s=%.03fs" , row .aName , * row .aTime , row .bName , * row .bTime ))
438+ buffer .Html (`">` )
439+
440+ switch {
441+
442+ case * row .aTime < minTime && * row .bTime < minTime :
443+ buffer .Text ("both < 50ms" )
444+
445+ case * row .aTime > maxTime && * row .bTime < maxTime :
446+ buffer .Text (fmt .Sprintf ("%s is over %0.02fs" , row .aName , * row .aTime ))
447+
448+ case * row .bTime > maxTime && * row .aTime < maxTime :
449+ buffer .Text (fmt .Sprintf ("%s is over %0.02fs" , row .bName , * row .bTime ))
450+
451+ default :
452+
453+ if * row .responseTimeDelta > 0 {
454+ buffer .Text (fmt .Sprintf ("%.01f%% faster" , * row .responseTimeDelta ))
455+ } else {
456+ buffer .Text (fmt .Sprintf ("%.01f%% slower" , - (* row .responseTimeDelta )))
457+ }
458+
459+ }
460+ buffer .Html (`</span>` )
410461 } else {
411462 buffer .Text ("n/a" )
412463 }
@@ -536,7 +587,7 @@ func (qmc *QuesmaManagementConsole) generateABPanelDetails(dashboardId, panelId
536587
537588 buffer .Html (`<main id="ab_testing_dashboard">` )
538589
539- buffer .Html (`<h2>A/B Testing - Panel Details</h2>` )
590+ buffer .Html (`<h2>Compatibility report - Panel Details</h2>` )
540591 buffer .Html (`<h3>` )
541592 buffer .Text (fmt .Sprintf ("Dashboard: %s" , dashboardName ))
542593 buffer .Html (`</h3>` )
@@ -671,7 +722,7 @@ func (qmc *QuesmaManagementConsole) generateABMismatchDetails(dashboardId, panel
671722
672723 buffer .Html (`<main id="ab_testing_dashboard">` )
673724
674- buffer .Html (`<h2>A/B Testing - Panel requests</h2>` )
725+ buffer .Html (`<h2>Compatibility report - Panel requests</h2>` )
675726
676727 buffer .Html (`<h3>` )
677728 buffer .Text (fmt .Sprintf ("Dashboard: %s" , dashboardName ))
@@ -796,7 +847,7 @@ func (qmc *QuesmaManagementConsole) generateABSingleRequest(requestId string) []
796847 buffer := newBufferWithHead ()
797848 buffer .Html (`<main id="ab_testing_dashboard">` )
798849
799- buffer .Html (`<h2>A/B Testing - Request Results </h2>` )
850+ buffer .Html (`<h2>Compatibility report - Request Results </h2>` )
800851
801852 fmtAny := func (value any ) string {
802853 if value == nil {
0 commit comments