@@ -350,52 +350,67 @@ GROUP BY
350350-- GetTemplateAppInsightsByTemplate is used for Prometheus metrics. Keep
351351-- in sync with GetTemplateAppInsights and UpsertTemplateUsageStats.
352352WITH
353+ filtered_stats AS (
354+ SELECT
355+ was .workspace_id ,
356+ was .user_id ,
357+ was .agent_id ,
358+ was .access_method ,
359+ was .slug_or_port ,
360+ was .session_started_at ,
361+ was .session_ended_at
362+ FROM
363+ workspace_app_stats AS was
364+ WHERE
365+ was .session_ended_at >= @start_time::timestamptz
366+ AND was .session_started_at < @end_time::timestamptz
367+ ),
353368 -- This CTE is used to explode app usage into minute buckets, then
354369 -- flatten the users app usage within the template so that usage in
355370 -- multiple workspaces under one template is only counted once for
356371 -- every minute.
357372 app_insights AS (
358373 SELECT
359374 w .template_id ,
360- was .user_id ,
375+ fs .user_id ,
361376 -- Both app stats and agent stats track web terminal usage, but
362377 -- by different means. The app stats value should be more
363378 -- accurate so we don't want to discard it just yet.
364379 CASE
365- WHEN was .access_method = ' terminal'
380+ WHEN fs .access_method = ' terminal'
366381 THEN ' [terminal]' -- Unique name, app names can't contain brackets.
367- ELSE was .slug_or_port
382+ ELSE fs .slug_or_port
368383 END::text AS app_name,
369384 COALESCE(wa .display_name , ' ' ) AS display_name,
370385 (wa .slug IS NOT NULL )::boolean AS is_app,
371386 COUNT (DISTINCT s .minute_bucket ) AS app_minutes
372387 FROM
373- workspace_app_stats AS was
388+ filtered_stats AS fs
374389 JOIN
375390 workspaces AS w
376391 ON
377- w .id = was .workspace_id
392+ w .id = fs .workspace_id
378393 -- We do a left join here because we want to include user IDs that have used
379394 -- e.g. ports when counting active users.
380395 LEFT JOIN
381396 workspace_apps wa
382397 ON
383- wa .agent_id = was .agent_id
384- AND wa .slug = was .slug_or_port
398+ wa .agent_id = fs .agent_id
399+ AND wa .slug = fs .slug_or_port
385400 -- Generate a series of minute buckets for each session for computing the
386401 -- mintes/bucket.
387402 CROSS JOIN
388403 generate_series(
389- date_trunc(' minute' , was .session_started_at ),
404+ date_trunc(' minute' , fs .session_started_at ),
390405 -- Subtract 1 μs to avoid creating an extra series.
391- date_trunc(' minute' , was .session_ended_at - ' 1 microsecond' ::interval),
406+ date_trunc(' minute' , fs .session_ended_at - ' 1 microsecond' ::interval),
392407 ' 1 minute' ::interval
393408 ) AS s(minute_bucket)
394409 WHERE
395410 s .minute_bucket >= @start_time::timestamptz
396411 AND s .minute_bucket < @end_time::timestamptz
397412 GROUP BY
398- w .template_id , was .user_id , was .access_method , was .slug_or_port , wa .display_name , wa .slug
413+ w .template_id , fs .user_id , fs .access_method , fs .slug_or_port , wa .display_name , wa .slug
399414 )
400415
401416SELECT
@@ -480,37 +495,52 @@ WITH
480495 FROM
481496 template_usage_stats
482497 ),
498+ filtered_app_stats AS (
499+ SELECT
500+ was .workspace_id ,
501+ was .user_id ,
502+ was .agent_id ,
503+ was .access_method ,
504+ was .slug_or_port ,
505+ was .session_started_at ,
506+ was .session_ended_at
507+ FROM
508+ workspace_app_stats AS was
509+ WHERE
510+ was .session_ended_at >= (SELECT t FROM latest_start)
511+ AND was .session_started_at < NOW()
512+ ),
483513 workspace_app_stat_buckets AS (
484514 SELECT
485515 -- Truncate the minute to the nearest half hour, this is the bucket size
486516 -- for the data.
487517 date_trunc(' hour' , s .minute_bucket ) + trunc(date_part(' minute' , s .minute_bucket ) / 30 ) * 30 * ' 1 minute' ::interval AS time_bucket,
488518 w .template_id ,
489- was .user_id ,
519+ fas .user_id ,
490520 -- Both app stats and agent stats track web terminal usage, but
491521 -- by different means. The app stats value should be more
492522 -- accurate so we don't want to discard it just yet.
493523 CASE
494- WHEN was .access_method = ' terminal'
524+ WHEN fas .access_method = ' terminal'
495525 THEN ' [terminal]' -- Unique name, app names can't contain brackets.
496- ELSE was .slug_or_port
526+ ELSE fas .slug_or_port
497527 END AS app_name,
498528 COUNT (DISTINCT s .minute_bucket ) AS app_minutes,
499529 -- Store each unique minute bucket for later merge between datasets.
500530 array_agg(DISTINCT s .minute_bucket ) AS minute_buckets
501531 FROM
502- workspace_app_stats AS was
532+ filtered_app_stats AS fas
503533 JOIN
504534 workspaces AS w
505535 ON
506- w .id = was .workspace_id
536+ w .id = fas .workspace_id
507537 -- Generate a series of minute buckets for each session for computing the
508538 -- mintes/bucket.
509539 CROSS JOIN
510540 generate_series(
511- date_trunc(' minute' , was .session_started_at ),
541+ date_trunc(' minute' , fas .session_started_at ),
512542 -- Subtract 1 μs to avoid creating an extra series.
513- date_trunc(' minute' , was .session_ended_at - ' 1 microsecond' ::interval),
543+ date_trunc(' minute' , fas .session_ended_at - ' 1 microsecond' ::interval),
514544 ' 1 minute' ::interval
515545 ) AS s(minute_bucket)
516546 WHERE
519549 s .minute_bucket >= (SELECT t FROM latest_start)
520550 AND s .minute_bucket < NOW()
521551 GROUP BY
522- time_bucket, w .template_id , was .user_id , was .access_method , was .slug_or_port
552+ time_bucket, w .template_id , fas .user_id , fas .access_method , fas .slug_or_port
523553 ),
524554 agent_stats_buckets AS (
525555 SELECT
0 commit comments