+107
docs/tools/logfire-client-traffic-dashboard.sql
+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
+
*/