@@ -7,7 +7,7 @@ use crate::{
77 schema:: {
88 CustomVariable , Dashboard , DashboardBuilder , DataLink , Datasource , FieldConfig ,
99 FieldConfigCustom , FieldConfigDefaults , GridPos , LogOptions , LogPanel , Panel , Target ,
10- TimeSeriesPanel , Transformation ,
10+ TextPanel , TimeSeriesPanel , Transformation ,
1111 } ,
1212 sql:: Query ,
1313 util:: { Join , UrlBuilder } ,
@@ -55,11 +55,16 @@ fn overview_count_panel(
5555 application : Application ,
5656 channel : ReleaseChannel ,
5757) -> Panel {
58- let query = if application == Application :: Desktop {
59- desktop_count_query ( format ! ( "'{channel}'" ) )
60- } else {
61- mobile_count_query ( config, format ! ( "'{channel}'" ) )
62- } ;
58+ if application == Application :: Ios && channel == ReleaseChannel :: Nightly {
59+ return TextPanel {
60+ content : "## N/A" . into ( ) ,
61+ mode : "markdown" . into ( ) ,
62+ grid_pos : GridPos :: height ( 8 ) ,
63+ }
64+ . into ( ) ;
65+ }
66+
67+ let query = count_query ( config, application, format ! ( "'{channel}'" ) ) ;
6368
6469 TimeSeriesPanel {
6570 title : application. display_name ( channel) ,
@@ -106,74 +111,43 @@ fn overview_count_panel(
106111 . into ( )
107112}
108113
109- /// Subquery to fetch general sync info for desktop
110- ///
111- /// We use subqueries to smooth out the differences between desktop and mobile telemetry.
112- fn desktop_count_query ( channel_expr : String ) -> String {
113- format ! (
114- "\
115- WITH counts AS
116- (SELECT
117- $__timeGroup(submission_timestamp, $__interval) as time,
118- JSON_VALUE(engine.name) AS engine_name,
119- COUNTIF(syncs.failureReason IS NOT NULL OR engine.failureReason IS NOT NULL) as count_total_errors,
120- COUNTIF(syncs.failureReason IS NULL
121- AND engine.failureReason IS NULL
122- AND (engine.incoming IS NOT NULL
123- OR engine.outgoing IS NOT NULL
124- OR engine.took IS NOT NULL)) AS count_success,
125- FROM firefox_desktop.sync
126- CROSS JOIN UNNEST(JSON_QUERY_ARRAY(metrics.object.syncs_syncs)) as syncs
127- CROSS JOIN UNNEST(JSON_QUERY_ARRAY(syncs,'$.engines')) AS engine
128- WHERE metrics IS NOT NULL
129- AND JSON_VALUE(engine.name) NOT IN ('bookmarks', 'extension-storage')
130- AND normalized_channel = {channel_expr}
131- AND $__timeFilter(submission_timestamp)
132- GROUP BY time, engine_name)
133- SELECT engine_name,
134- time,
135- count_success / (count_success + count_total_errors) * 100 AS success_rate,
136- FROM counts
137- ORDER BY time" )
138- }
114+ /// Query to fetch sync success rates
115+ fn count_query ( config : & TeamConfig , application : Application , channel_expr : String ) -> String {
116+ let table_name = if application == Application :: Desktop {
117+ "desktop_v1"
118+ } else {
119+ "mobile_v1"
120+ } ;
121+ let application_where = match application {
122+ Application :: Desktop => "application = 'desktop'" ,
123+ Application :: Ios => "application = 'firefox-ios'" ,
124+ Application :: Android => "application = 'firefox-android'" ,
125+ } ;
139126
140- /// Subquery to fetch general sync info for mobile
141- ///
142- /// We use subqueries to smooth out the differences between desktop and mobile telemetry.
143- fn mobile_count_query ( config : & TeamConfig , channel_expr : String ) -> String {
144- let parts = config
127+ let mut engines: Vec < _ > = config
145128 . components
146129 . iter ( )
147130 . flat_map ( |c| c. sync_engines ( ) )
148- . map ( |engine_name| {
149- let table_name = format ! ( "{}_sync" , engine_name. replace( "-" , "_" ) ) ;
150- format ! (
151- "\
152- SELECT '{engine_name}' AS engine_name,
153- $__timeGroup(submission_timestamp, $__interval) as time,
154- SAFE_DIVIDE(
155- -- 100 * success count
156- 100 * COUNTIF(
157- (metrics.labeled_counter.{table_name}_v2_incoming IS NOT NULL
158- OR metrics.labeled_counter.{table_name}_v2_outgoing IS NOT NULL)
159- AND metrics.labeled_string.{table_name}_v2_failure_reason IS NULL
160- ),
161- -- count success or failures
162- COUNTIF(
163- metrics.labeled_string.{table_name}_v2_failure_reason IS NOT NULL
164- OR metrics.labeled_counter.{table_name}_v2_outgoing IS NOT NULL
165- OR metrics.labeled_counter.{table_name}_v2_incoming IS NOT NULL
166- )
167- ) AS success_rate,
168- FROM mozdata.fenix.{table_name}
169- WHERE normalized_channel={channel_expr} AND $__timeFilter(submission_timestamp)
170- GROUP BY 1, 2"
171- )
172- } )
173- . collect :: < Vec < _ > > ( ) ;
131+ . map ( |e| format ! ( "'{e}'" ) )
132+ . collect ( ) ;
133+ engines. sort_unstable ( ) ;
134+ engines. dedup ( ) ;
135+ let engines_where = format ! ( "engine_name IN ({})" , engines. join( ", " ) ) ;
136+
174137 format ! (
175- "{}\n ORDER BY engine_name, time" ,
176- parts. join( "\n UNION ALL\n " )
138+ "\
139+ SELECT
140+ TIMESTAMP(submission_date) as time,
141+ engine_name,
142+ success_rate
143+ FROM
144+ moz-fx-data-shared-prod.sync_derived.{table_name}
145+ WHERE
146+ channel = {channel_expr}
147+ AND $__timeFilter(TIMESTAMP(submission_date))
148+ AND {application_where}
149+ AND {engines_where}
150+ ORDER BY time"
177151 )
178152}
179153
0 commit comments