Skip to content

Commit f89acd0

Browse files
authored
Switch to ETL for sync metrics (#7411)
This speeds up the queries significantly. Before they were so slow that we couldn't see the desktop ones. Also added a "N/A" panel for firefox-ios/nightly since that no longer exists.
1 parent d2faad8 commit f89acd0

2 files changed

Lines changed: 59 additions & 69 deletions

File tree

tools/generate-rust-dashboards/src/metrics/sync.rs

Lines changed: 43 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
"{}\nORDER BY engine_name, time",
176-
parts.join("\nUNION 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

tools/generate-rust-dashboards/src/schema.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub struct Dashboard {
3535
#[serde(rename_all = "lowercase")]
3636
pub enum Panel {
3737
Row(PanelRow),
38+
Text(TextPanel),
3839
Logs(LogPanel),
3940
TimeSeries(TimeSeriesPanel),
4041
PieChart(PieChartPanel),
@@ -48,6 +49,14 @@ pub struct PanelRow {
4849
pub grid_pos: GridPos,
4950
}
5051

52+
#[derive(Default, Serialize)]
53+
#[serde(rename_all = "camelCase")]
54+
pub struct TextPanel {
55+
pub content: String,
56+
pub mode: String,
57+
pub grid_pos: GridPos,
58+
}
59+
5160
#[derive(Default, Serialize)]
5261
#[serde(rename_all = "camelCase")]
5362
pub struct LogPanel {
@@ -482,6 +491,7 @@ impl Panel {
482491
fn grid_pos_mut(&mut self) -> &mut GridPos {
483492
match self {
484493
Self::Row(p) => &mut p.grid_pos,
494+
Self::Text(p) => &mut p.grid_pos,
485495
Self::Logs(p) => &mut p.grid_pos,
486496
Self::TimeSeries(p) => &mut p.grid_pos,
487497
Self::PieChart(p) => &mut p.grid_pos,
@@ -495,6 +505,12 @@ impl From<PanelRow> for Panel {
495505
}
496506
}
497507

508+
impl From<TextPanel> for Panel {
509+
fn from(p: TextPanel) -> Self {
510+
Self::Text(p)
511+
}
512+
}
513+
498514
impl From<LogPanel> for Panel {
499515
fn from(p: LogPanel) -> Self {
500516
Self::Logs(p)

0 commit comments

Comments
 (0)