mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat(coderd/database): use template_usage_stats in GetTemplateInsights query (#12666)
This PR updates the `GetTemplateInsights` query to use rolled up `template_usage_stats` instead of raw agent and app stats.
This commit is contained in:
@@ -99,40 +99,67 @@ GROUP BY users.id, username, avatar_url
|
||||
ORDER BY user_id ASC;
|
||||
|
||||
-- name: GetTemplateInsights :one
|
||||
-- GetTemplateInsights has a granularity of 5 minutes where if a session/app was
|
||||
-- in use during a minute, we will add 5 minutes to the total usage for that
|
||||
-- session/app (per user).
|
||||
WITH agent_stats_by_interval_and_user AS (
|
||||
SELECT
|
||||
date_trunc('minute', was.created_at),
|
||||
was.user_id,
|
||||
array_agg(was.template_id) AS template_ids,
|
||||
CASE WHEN SUM(was.session_count_vscode) > 0 THEN 60 ELSE 0 END AS usage_vscode_seconds,
|
||||
CASE WHEN SUM(was.session_count_jetbrains) > 0 THEN 60 ELSE 0 END AS usage_jetbrains_seconds,
|
||||
CASE WHEN SUM(was.session_count_reconnecting_pty) > 0 THEN 60 ELSE 0 END AS usage_reconnecting_pty_seconds,
|
||||
CASE WHEN SUM(was.session_count_ssh) > 0 THEN 60 ELSE 0 END AS usage_ssh_seconds
|
||||
FROM workspace_agent_stats was
|
||||
WHERE
|
||||
was.created_at >= @start_time::timestamptz
|
||||
AND was.created_at < @end_time::timestamptz
|
||||
AND was.connection_count > 0
|
||||
AND CASE WHEN COALESCE(array_length(@template_ids::uuid[], 1), 0) > 0 THEN was.template_id = ANY(@template_ids::uuid[]) ELSE TRUE END
|
||||
GROUP BY date_trunc('minute', was.created_at), was.user_id
|
||||
), template_ids AS (
|
||||
SELECT array_agg(DISTINCT template_id) AS ids
|
||||
FROM agent_stats_by_interval_and_user, unnest(template_ids) template_id
|
||||
WHERE template_id IS NOT NULL
|
||||
)
|
||||
-- GetTemplateInsights returns the aggregate user-produced usage of all
|
||||
-- workspaces in a given timeframe. The template IDs, active users, and
|
||||
-- usage_seconds all reflect any usage in the template, including apps.
|
||||
--
|
||||
-- When combining data from multiple templates, we must make a guess at
|
||||
-- how the user behaved for the 30 minute interval. In this case we make
|
||||
-- the assumption that if the user used two workspaces for 15 minutes,
|
||||
-- they did so sequentially, thus we sum the usage up to a maximum of
|
||||
-- 30 minutes with LEAST(SUM(n), 30).
|
||||
WITH
|
||||
insights AS (
|
||||
SELECT
|
||||
user_id,
|
||||
-- See motivation in GetTemplateInsights for LEAST(SUM(n), 30).
|
||||
LEAST(SUM(usage_mins), 30) AS usage_mins,
|
||||
LEAST(SUM(ssh_mins), 30) AS ssh_mins,
|
||||
LEAST(SUM(sftp_mins), 30) AS sftp_mins,
|
||||
LEAST(SUM(reconnecting_pty_mins), 30) AS reconnecting_pty_mins,
|
||||
LEAST(SUM(vscode_mins), 30) AS vscode_mins,
|
||||
LEAST(SUM(jetbrains_mins), 30) AS jetbrains_mins
|
||||
FROM
|
||||
template_usage_stats
|
||||
WHERE
|
||||
start_time >= @start_time::timestamptz
|
||||
AND end_time <= @end_time::timestamptz
|
||||
AND CASE WHEN COALESCE(array_length(@template_ids::uuid[], 1), 0) > 0 THEN template_id = ANY(@template_ids::uuid[]) ELSE TRUE END
|
||||
GROUP BY
|
||||
start_time, user_id
|
||||
),
|
||||
templates AS (
|
||||
SELECT
|
||||
array_agg(DISTINCT template_id) AS template_ids,
|
||||
array_agg(DISTINCT template_id) FILTER (WHERE ssh_mins > 0) AS ssh_template_ids,
|
||||
array_agg(DISTINCT template_id) FILTER (WHERE sftp_mins > 0) AS sftp_template_ids,
|
||||
array_agg(DISTINCT template_id) FILTER (WHERE reconnecting_pty_mins > 0) AS reconnecting_pty_template_ids,
|
||||
array_agg(DISTINCT template_id) FILTER (WHERE vscode_mins > 0) AS vscode_template_ids,
|
||||
array_agg(DISTINCT template_id) FILTER (WHERE jetbrains_mins > 0) AS jetbrains_template_ids
|
||||
FROM
|
||||
template_usage_stats
|
||||
WHERE
|
||||
start_time >= @start_time::timestamptz
|
||||
AND end_time <= @end_time::timestamptz
|
||||
AND CASE WHEN COALESCE(array_length(@template_ids::uuid[], 1), 0) > 0 THEN template_id = ANY(@template_ids::uuid[]) ELSE TRUE END
|
||||
)
|
||||
|
||||
SELECT
|
||||
COALESCE((SELECT ids FROM template_ids), '{}')::uuid[] AS template_ids,
|
||||
-- Return IDs so we can combine this with GetTemplateAppInsights.
|
||||
COALESCE(array_agg(DISTINCT user_id), '{}')::uuid[] AS active_user_ids,
|
||||
COALESCE(SUM(usage_vscode_seconds), 0)::bigint AS usage_vscode_seconds,
|
||||
COALESCE(SUM(usage_jetbrains_seconds), 0)::bigint AS usage_jetbrains_seconds,
|
||||
COALESCE(SUM(usage_reconnecting_pty_seconds), 0)::bigint AS usage_reconnecting_pty_seconds,
|
||||
COALESCE(SUM(usage_ssh_seconds), 0)::bigint AS usage_ssh_seconds
|
||||
FROM agent_stats_by_interval_and_user;
|
||||
COALESCE((SELECT template_ids FROM templates), '{}')::uuid[] AS template_ids, -- Includes app usage.
|
||||
COALESCE((SELECT ssh_template_ids FROM templates), '{}')::uuid[] AS ssh_template_ids,
|
||||
COALESCE((SELECT sftp_template_ids FROM templates), '{}')::uuid[] AS sftp_template_ids,
|
||||
COALESCE((SELECT reconnecting_pty_template_ids FROM templates), '{}')::uuid[] AS reconnecting_pty_template_ids,
|
||||
COALESCE((SELECT vscode_template_ids FROM templates), '{}')::uuid[] AS vscode_template_ids,
|
||||
COALESCE((SELECT jetbrains_template_ids FROM templates), '{}')::uuid[] AS jetbrains_template_ids,
|
||||
COALESCE(COUNT(DISTINCT user_id), 0)::bigint AS active_users, -- Includes app usage.
|
||||
COALESCE(SUM(usage_mins) * 60, 0)::bigint AS usage_total_seconds, -- Includes app usage.
|
||||
COALESCE(SUM(ssh_mins) * 60, 0)::bigint AS usage_ssh_seconds,
|
||||
COALESCE(SUM(sftp_mins) * 60, 0)::bigint AS usage_sftp_seconds,
|
||||
COALESCE(SUM(reconnecting_pty_mins) * 60, 0)::bigint AS usage_reconnecting_pty_seconds,
|
||||
COALESCE(SUM(vscode_mins) * 60, 0)::bigint AS usage_vscode_seconds,
|
||||
COALESCE(SUM(jetbrains_mins) * 60, 0)::bigint AS usage_jetbrains_seconds
|
||||
FROM
|
||||
insights;
|
||||
|
||||
-- name: GetTemplateInsightsByTemplate :many
|
||||
WITH agent_stats_by_interval_and_user AS (
|
||||
|
||||
Reference in New Issue
Block a user