Spaces:
Running
Running
File size: 5,388 Bytes
ee68d8e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | -- Upgrade dashboard_summary: add hourly_stats column + update refresh function
-- Run this in Supabase SQL Editor (safe to run on existing table)
-- 1. Add hourly_stats column if missing
ALTER TABLE dashboard_summary
ADD COLUMN IF NOT EXISTS hourly_stats jsonb DEFAULT '[]'::jsonb;
-- 2. Replace the refresh function with hourly support
CREATE OR REPLACE FUNCTION refresh_dashboard_summary()
RETURNS void AS $$
DECLARE
_daily jsonb;
_hourly jsonb;
_top jsonb;
_os jsonb;
_versions jsonb;
_total_tokens bigint;
_total_cost numeric;
_total_requests int;
_unique_instances int;
_active_days int;
BEGIN
-- Daily totals: MAX per instance per day (beacon is cumulative), then SUM across instances
WITH instance_daily AS (
SELECT
instance_id,
created_at::date AS day,
MAX(COALESCE(tokens_saved, 0)) AS tokens_saved,
MAX(COALESCE(cost_saved_usd, 0)) AS cost_saved,
MAX(COALESCE(requests, 0)) AS requests
FROM proxy_telemetry_v2
GROUP BY instance_id, created_at::date
),
daily_agg AS (
SELECT
day,
SUM(tokens_saved) AS tokens_saved,
SUM(cost_saved)::numeric(12,2) AS cost_saved,
SUM(requests) AS requests,
COUNT(DISTINCT instance_id) AS instances
FROM instance_daily
GROUP BY day
ORDER BY day
)
SELECT
COALESCE(jsonb_agg(jsonb_build_object(
'date', day,
'tokens_saved', tokens_saved,
'cost_saved', cost_saved,
'requests', requests,
'instances', instances
) ORDER BY day), '[]'::jsonb),
COALESCE(SUM(tokens_saved), 0),
COALESCE(SUM(cost_saved), 0),
COALESCE(SUM(requests), 0),
COUNT(DISTINCT day)
INTO _daily, _total_tokens, _total_cost, _total_requests, _active_days
FROM daily_agg;
-- Hourly totals: last 48 hours, MAX per instance per hour, then SUM across instances
WITH instance_hourly AS (
SELECT
instance_id,
date_trunc('hour', created_at) AS hour,
MAX(COALESCE(tokens_saved, 0)) AS tokens_saved,
MAX(COALESCE(cost_saved_usd, 0)) AS cost_saved,
MAX(COALESCE(requests, 0)) AS requests
FROM proxy_telemetry_v2
WHERE created_at >= now() - interval '48 hours'
GROUP BY instance_id, date_trunc('hour', created_at)
),
hourly_agg AS (
SELECT
hour,
SUM(tokens_saved) AS tokens_saved,
SUM(cost_saved)::numeric(12,2) AS cost_saved,
SUM(requests) AS requests,
COUNT(DISTINCT instance_id) AS instances
FROM instance_hourly
GROUP BY hour
ORDER BY hour
)
SELECT COALESCE(jsonb_agg(jsonb_build_object(
'hour', to_char(hour, 'YYYY-MM-DD HH24:MI'),
'tokens_saved', tokens_saved,
'cost_saved', cost_saved,
'requests', requests,
'instances', instances
) ORDER BY hour), '[]'::jsonb)
INTO _hourly
FROM hourly_agg;
-- Unique instances
SELECT COUNT(DISTINCT instance_id) INTO _unique_instances FROM proxy_telemetry_v2;
-- Top 20 instances by total tokens saved
WITH instance_totals AS (
SELECT
instance_id,
SUM(max_tokens) AS tokens_saved,
SUM(max_cost)::numeric(12,2) AS cost_saved,
MAX(os) AS os,
MAX(version) AS version
FROM (
SELECT
instance_id,
created_at::date,
MAX(COALESCE(tokens_saved, 0)) AS max_tokens,
MAX(COALESCE(cost_saved_usd, 0)) AS max_cost,
MAX(os) AS os,
MAX(headroom_version) AS version
FROM proxy_telemetry_v2
GROUP BY instance_id, created_at::date
) sub
GROUP BY instance_id
ORDER BY tokens_saved DESC
LIMIT 20
)
SELECT COALESCE(jsonb_agg(jsonb_build_object(
'instance_id', LEFT(instance_id, 8),
'tokens_saved', tokens_saved,
'cost_saved', cost_saved,
'os', SPLIT_PART(COALESCE(os, '?'), ' ', 1),
'version', version
) ORDER BY tokens_saved DESC), '[]'::jsonb)
INTO _top
FROM instance_totals;
-- OS breakdown
SELECT COALESCE(jsonb_object_agg(os_name, cnt), '{}'::jsonb)
INTO _os
FROM (
SELECT SPLIT_PART(COALESCE(os, '?'), ' ', 1) AS os_name, COUNT(*) AS cnt
FROM proxy_telemetry_v2
GROUP BY os_name
) sub;
-- Version breakdown
SELECT COALESCE(jsonb_object_agg(COALESCE(headroom_version, '?'), cnt), '{}'::jsonb)
INTO _versions
FROM (
SELECT headroom_version, COUNT(*) AS cnt
FROM proxy_telemetry_v2
GROUP BY headroom_version
) sub;
-- Upsert the single summary row
INSERT INTO dashboard_summary (id, updated_at, total_tokens_saved, total_cost_saved,
total_requests, unique_instances, active_days, daily_stats, hourly_stats,
top_instances, os_breakdown, version_breakdown)
VALUES ('current', now(), _total_tokens, _total_cost, _total_requests,
_unique_instances, _active_days, _daily, _hourly, _top, _os, _versions)
ON CONFLICT (id) DO UPDATE SET
updated_at = EXCLUDED.updated_at,
total_tokens_saved = EXCLUDED.total_tokens_saved,
total_cost_saved = EXCLUDED.total_cost_saved,
total_requests = EXCLUDED.total_requests,
unique_instances = EXCLUDED.unique_instances,
active_days = EXCLUDED.active_days,
daily_stats = EXCLUDED.daily_stats,
hourly_stats = EXCLUDED.hourly_stats,
top_instances = EXCLUDED.top_instances,
os_breakdown = EXCLUDED.os_breakdown,
version_breakdown = EXCLUDED.version_breakdown;
END;
$$ LANGUAGE plpgsql;
-- 3. Refresh now to populate hourly data
SELECT refresh_dashboard_summary();
|