Improve report field naming #44

Merged
wagesj45 merged 1 commit from codex/retool-reports-for-better-visualization into main 2025-07-19 04:17:51 -05:00
3 changed files with 49 additions and 22 deletions

View file

@ -2,30 +2,36 @@
label: Hits label: Hits
icon: pulse icon: pulse
chart: line chart: line
bucket: time_bucket
bucket_label: Time
query: | query: |
SELECT {bucket} AS bucket, SELECT {bucket} AS time_bucket,
COUNT(*) AS value COUNT(*) AS value
FROM logs FROM logs
GROUP BY bucket GROUP BY time_bucket
ORDER BY bucket ORDER BY time_bucket
- name: error_rate - name: error_rate
label: Error Rate (%) label: Error Rate (%)
icon: file-alert icon: file-alert
chart: line chart: line
bucket: time_bucket
bucket_label: Time
query: | query: |
SELECT {bucket} AS bucket, SELECT {bucket} AS time_bucket,
SUM(CASE WHEN status BETWEEN 400 AND 599 THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS value SUM(CASE WHEN status BETWEEN 400 AND 599 THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS value
FROM logs FROM logs
GROUP BY bucket GROUP BY time_bucket
ORDER BY bucket ORDER BY time_bucket
- name: cache_status_breakdown - name: cache_status_breakdown
label: Cache Status label: Cache Status
icon: archive icon: archive
chart: polarArea chart: polarArea
bucket: cache_status
bucket_label: Cache Status
query: | query: |
SELECT cache_status AS bucket, SELECT cache_status AS cache_status,
COUNT(*) AS value COUNT(*) AS value
FROM logs FROM logs
GROUP BY cache_status GROUP BY cache_status
@ -43,30 +49,36 @@
icon: globe icon: globe
chart: table chart: table
per_domain: false per_domain: false
bucket: domain
bucket_label: Domain
query: | query: |
SELECT host AS bucket, SELECT host AS domain,
COUNT(*) AS value COUNT(*) AS value
FROM logs FROM logs
GROUP BY host GROUP BY domain
ORDER BY value DESC ORDER BY value DESC
- name: bytes_sent - name: bytes_sent
label: Bytes Sent label: Bytes Sent
icon: upload icon: upload
chart: line chart: line
bucket: time_bucket
bucket_label: Time
query: | query: |
SELECT {bucket} AS bucket, SELECT {bucket} AS time_bucket,
SUM(bytes_sent) AS value SUM(bytes_sent) AS value
FROM logs FROM logs
GROUP BY bucket GROUP BY time_bucket
ORDER BY bucket ORDER BY time_bucket
- name: top_paths - name: top_paths
label: Top Paths label: Top Paths
icon: map icon: map
chart: table chart: table
bucket: path
bucket_label: Path
query: | query: |
SELECT path AS bucket, SELECT path AS path,
COUNT(*) AS value COUNT(*) AS value
FROM ( FROM (
SELECT substr(substr(request, instr(request, ' ') + 1), 1, SELECT substr(substr(request, instr(request, ' ') + 1), 1,
@ -81,8 +93,10 @@
label: User Agents label: User Agents
icon: user icon: user
chart: table chart: table
bucket: user_agent
bucket_label: User Agent
query: | query: |
SELECT user_agent AS bucket, SELECT user_agent AS user_agent,
COUNT(*) AS value COUNT(*) AS value
FROM logs FROM logs
GROUP BY user_agent GROUP BY user_agent
@ -93,11 +107,13 @@
label: Referrers label: Referrers
icon: link icon: link
chart: table chart: table
bucket: referrer
bucket_label: Referrer
query: | query: |
SELECT referer AS bucket, SELECT referer AS referrer,
COUNT(*) AS value COUNT(*) AS value
FROM logs FROM logs
GROUP BY referer GROUP BY referrer
ORDER BY value DESC ORDER BY value DESC
LIMIT 20 LIMIT 20
@ -105,17 +121,19 @@
label: HTTP Statuses label: HTTP Statuses
icon: server icon: server
chart: pie chart: pie
bucket: status_group
bucket_label: Status
query: | query: |
SELECT CASE SELECT CASE
WHEN status BETWEEN 200 AND 299 THEN '2xx' WHEN status BETWEEN 200 AND 299 THEN '2xx'
WHEN status BETWEEN 300 AND 399 THEN '3xx' WHEN status BETWEEN 300 AND 399 THEN '3xx'
WHEN status BETWEEN 400 AND 499 THEN '4xx' WHEN status BETWEEN 400 AND 499 THEN '4xx'
ELSE '5xx' ELSE '5xx'
END AS bucket, END AS status_group,
COUNT(*) AS value COUNT(*) AS value
FROM logs FROM logs
GROUP BY bucket GROUP BY status_group
ORDER BY bucket ORDER BY status_group
colors: colors:
- "#48c78e" - "#48c78e"
- "#209cee" - "#209cee"

View file

@ -169,6 +169,10 @@ def _generate_interval(interval: str, domain: Optional[str] = None) -> None:
} }
if "icon" in definition: if "icon" in definition:
entry["icon"] = definition["icon"] entry["icon"] = definition["icon"]
if "bucket" in definition:
entry["bucket"] = definition["bucket"]
if "bucket_label" in definition:
entry["bucket_label"] = definition["bucket_label"]
if "color" in definition: if "color" in definition:
entry["color"] = definition["color"] entry["color"] = definition["color"]
if "colors" in definition: if "colors" in definition:
@ -253,6 +257,10 @@ def _generate_global() -> None:
} }
if "icon" in definition: if "icon" in definition:
entry["icon"] = definition["icon"] entry["icon"] = definition["icon"]
if "bucket" in definition:
entry["bucket"] = definition["bucket"]
if "bucket_label" in definition:
entry["bucket_label"] = definition["bucket_label"]
if "color" in definition: if "color" in definition:
entry["color"] = definition["color"] entry["color"] = definition["color"]
if "colors" in definition: if "colors" in definition:

View file

@ -105,19 +105,20 @@
fetch(base + '/' + rep.json) fetch(base + '/' + rep.json)
.then(r => r.json()) .then(r => r.json())
.then(data => { .then(data => {
const bucketField = rep.bucket || 'bucket';
if (rep.chart === 'table') { if (rep.chart === 'table') {
const rows = data.map(x => [x.bucket, x.value]); const rows = data.map(x => [x[bucketField], x.value]);
new DataTable('#table-' + rep.name, { new DataTable('#table-' + rep.name, {
data: rows, data: rows,
columns: [ columns: [
{ title: 'Bucket' }, { title: rep.bucket_label || 'Bucket' },
{ title: 'Value' } { title: 'Value' }
] ]
}); });
return; return;
} }
const labels = data.map(x => x.bucket); const labels = data.map(x => x[bucketField]);
const values = data.map(x => x.value); const values = data.map(x => x.value);
const chartType = rep.chart === 'stackedBar' ? 'bar' : rep.chart; const chartType = rep.chart === 'stackedBar' ? 'bar' : rep.chart;
const options = { scales: { y: { beginAtZero: true } } }; const options = { scales: { y: { beginAtZero: true } } };