add another sql dashboard

Changed files
+107
docs
+107
docs/tools/logfire-client-traffic-dashboard.sql
··· 1 + -- Client Traffic Dashboard 2 + -- Shows traffic breakdown by client type (SDK, MCP, browser) 3 + -- Uses client_type and client_version attributes added via request_attributes_mapper 4 + 5 + -- Main Dashboard: Traffic by Client Type 6 + -- Shows request counts, latency, and error rates grouped by client source 7 + -- Groups by client_type only (version shown in separate query for SDK/MCP) 8 + WITH client_requests AS ( 9 + SELECT 10 + attributes->>'client_type' AS client_type, 11 + span_name, 12 + duration, 13 + start_timestamp, 14 + otel_status_code, 15 + (attributes->>'http.status_code')::int AS status_code 16 + FROM records 17 + WHERE 18 + kind = 'span' 19 + AND attributes->>'client_type' IS NOT NULL 20 + AND (span_name LIKE 'GET %' OR span_name LIKE 'POST %' OR span_name LIKE 'DELETE %' OR span_name LIKE 'PATCH %') 21 + ) 22 + SELECT 23 + client_type AS "Client Type", 24 + COUNT(*) AS "Requests", 25 + ROUND(AVG(duration * 1000)::numeric, 2) AS "Avg (ms)", 26 + ROUND(PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY duration * 1000)::numeric, 2) AS "p95 (ms)", 27 + COUNT(*) FILTER (WHERE status_code >= 400) AS "Errors", 28 + ROUND((COUNT(*) FILTER (WHERE status_code >= 400)::numeric / NULLIF(COUNT(*), 0) * 100), 2) AS "Error %" 29 + FROM client_requests 30 + GROUP BY client_type 31 + ORDER BY COUNT(*) DESC; 32 + 33 + 34 + -- Alternative: Traffic Over Time by Client Type 35 + -- Uncomment to see hourly breakdown of traffic sources 36 + /* 37 + SELECT 38 + DATE_TRUNC('hour', start_timestamp) AS "Hour", 39 + attributes->>'client_type' AS "Client Type", 40 + COUNT(*) AS "Requests", 41 + ROUND(AVG(duration * 1000)::numeric, 2) AS "Avg (ms)" 42 + FROM records 43 + WHERE 44 + kind = 'span' 45 + AND attributes->>'client_type' IS NOT NULL 46 + AND (span_name LIKE 'GET %' OR span_name LIKE 'POST %' OR span_name LIKE 'DELETE %') 47 + GROUP BY DATE_TRUNC('hour', start_timestamp), attributes->>'client_type' 48 + ORDER BY "Hour" DESC, "Requests" DESC 49 + LIMIT 100; 50 + */ 51 + 52 + 53 + -- Alternative: Top Endpoints by Client Type 54 + -- Uncomment to see which endpoints each client type uses most 55 + /* 56 + SELECT 57 + attributes->>'client_type' AS "Client Type", 58 + span_name AS "Endpoint", 59 + COUNT(*) AS "Requests", 60 + ROUND(AVG(duration * 1000)::numeric, 2) AS "Avg (ms)" 61 + FROM records 62 + WHERE 63 + kind = 'span' 64 + AND attributes->>'client_type' IS NOT NULL 65 + AND (span_name LIKE 'GET %' OR span_name LIKE 'POST %' OR span_name LIKE 'DELETE %') 66 + GROUP BY attributes->>'client_type', span_name 67 + ORDER BY attributes->>'client_type', COUNT(*) DESC 68 + LIMIT 50; 69 + */ 70 + 71 + 72 + -- Alternative: SDK/MCP Version Distribution 73 + -- Uncomment to see version adoption for programmatic clients 74 + /* 75 + SELECT 76 + attributes->>'client_type' AS "Client Type", 77 + attributes->>'client_version' AS "Version", 78 + COUNT(*) AS "Requests", 79 + MIN(start_timestamp) AS "First Seen", 80 + MAX(start_timestamp) AS "Last Seen" 81 + FROM records 82 + WHERE 83 + kind = 'span' 84 + AND attributes->>'client_type' IN ('sdk', 'mcp') 85 + AND attributes->>'client_version' IS NOT NULL 86 + GROUP BY attributes->>'client_type', attributes->>'client_version' 87 + ORDER BY attributes->>'client_type', COUNT(*) DESC; 88 + */ 89 + 90 + 91 + -- Alternative: Recent SDK/MCP Requests (Debug View) 92 + -- Uncomment to see individual requests from programmatic clients 93 + /* 94 + SELECT 95 + start_timestamp AS "Time", 96 + attributes->>'client_type' AS "Client", 97 + attributes->>'client_version' AS "Version", 98 + span_name AS "Endpoint", 99 + ROUND(duration * 1000, 2) AS "Duration (ms)", 100 + (attributes->>'http.status_code')::int AS "Status" 101 + FROM records 102 + WHERE 103 + kind = 'span' 104 + AND attributes->>'client_type' IN ('sdk', 'mcp') 105 + ORDER BY start_timestamp DESC 106 + LIMIT 25; 107 + */