Skip to content

feat: expose insights into user activity #9807

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 26 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Adjust SQL query
  • Loading branch information
mtojek committed Sep 22, 2023
commit 7109d92857aa410600151b6ad5b19232c42eaa2c
52 changes: 45 additions & 7 deletions coderd/database/queries.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 45 additions & 7 deletions coderd/database/queries/insights.sql
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ ORDER BY user_id ASC;
-- GetUserActivityInsights returns the ranking with top active users.
-- The result can be filtered on template_ids, meaning only user data from workspaces
-- based on those templates will be included.
WITH app_stats_by_user_and_agent AS (
WITH app_stats AS (
SELECT
s.start_time,
60 as seconds,
was.user_id,
w.template_id,
was.user_id
60 as seconds
FROM workspace_app_stats was
JOIN workspaces w ON (
w.id = was.workspace_id
Expand All @@ -50,17 +50,55 @@ WITH app_stats_by_user_and_agent AS (
-- Subtract one minute because the series only contains the start time.
AND s.start_time < (@end_time::timestamptz) - '1 minute'::interval
GROUP BY s.start_time, w.template_id, was.user_id
), session_stats AS (
SELECT
date_trunc('minute', was.created_at) as start_time,
was.user_id,
was.template_id,
CASE WHEN
SUM(was.session_count_vscode) > 0 OR
SUM(was.session_count_jetbrains) > 0 OR
SUM(was.session_count_reconnecting_pty) > 0 OR
SUM(was.session_count_ssh) > 0
THEN 60 ELSE 0 END as 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 w.template_id = ANY(@template_ids::uuid[]) ELSE TRUE END
GROUP BY date_trunc('minute', was.created_at), was.user_id, was.template_id
), combined_stats AS (
SELECT
user_id,
template_id,
start_time,
seconds
FROM app_stats
UNION ALL
SELECT
user_id,
template_id,
start_time,
seconds
FROM session_stats
), distinct_combined_stats AS (
SELECT DISTINCT
user_id,
template_id,
start_time,
seconds
FROM combined_stats
Copy link
Member

@mafredri mafredri Sep 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could remove this additional step if you change UNION ALL to UNION above, it'll remove duplicates.

However, in this instance I'm not sure if we should sum template IDs separately. Say you use template A and B concurrently for 1h, you will be listed as 2h in the stats now. Perhaps instead we should modify this distinct to be a group by (user, start time) with array_agg on the templates. Not sure about this, but putting it out there...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could remove this additional step if you change UNION ALL to UNION above, it'll remove duplicates.

Done! Thanks for the suggestion.

Say you use template A and B concurrently for 1h, you will be listed as 2h in the stats now.

It might be a business question, as it indicates the total duration the user spent working with the specific template. I would rather keep it as is rather than "online presence". Anyway, I will describe and cover it with tests 👍

)

SELECT
users.id as user_id,
users.username,
users.avatar_url,
array_agg(DISTINCT template_id)::uuid[] AS template_ids,
SUM(seconds) AS usage_seconds
FROM app_stats_by_user_and_agent
JOIN users ON (users.id = app_stats_by_user_and_agent.user_id)
GROUP BY user_id, username, avatar_url
FROM distinct_combined_stats
JOIN users ON (users.id = distinct_combined_stats.user_id)
GROUP BY users.id, username, avatar_url
ORDER BY user_id ASC;

-- name: GetTemplateInsights :one
Expand Down