+13
src/cache.ts
+13
src/cache.ts
···
1836
1836
}
1837
1837
1838
1838
/**
1839
+
* Gets total count of unique user agents
1840
+
* @returns Total count of unique user agents
1841
+
*/
1842
+
async getUserAgentCount(): Promise<number> {
1843
+
const result = this.db
1844
+
.query(
1845
+
`SELECT COUNT(*) as count FROM user_agent_stats WHERE user_agent IS NOT NULL`,
1846
+
)
1847
+
.get() as { count: number };
1848
+
return result?.count || 0;
1849
+
}
1850
+
1851
+
/**
1839
1852
* Gets referer stats from cumulative stats table
1840
1853
* @returns Referer host data sorted by hits
1841
1854
*/
+8
-8
src/dashboard.html
+8
-8
src/dashboard.html
···
736
736
}
737
737
738
738
const stats = await statsRes.json();
739
-
const userAgents = await uaRes.json();
739
+
const uaData = await uaRes.json();
740
740
const referers = await refRes.json();
741
741
742
742
// Update stats cards
743
743
document.getElementById('totalRequests').textContent = formatNumber(stats.totalRequests || 0);
744
744
document.getElementById('avgResponseTime').textContent = formatMs(stats.averageResponseTime);
745
745
document.getElementById('uptime').textContent = stats.uptime ? `${stats.uptime.toFixed(1)}%` : '-';
746
-
document.getElementById('uniqueAgents').textContent = formatNumber(userAgents.length || 0);
746
+
document.getElementById('uniqueAgents').textContent = formatNumber(uaData.totalCount || 0);
747
747
748
748
// Update chart
749
749
currentTrafficData = trafficData;
750
750
initChart(trafficData);
751
751
752
752
// Update user agents and referers
753
-
allUserAgents = userAgents;
754
-
renderTrafficSources(userAgents, referers);
753
+
allUserAgents = uaData.userAgents;
754
+
renderTrafficSources(uaData.userAgents, referers);
755
755
updateLastUpdated();
756
756
757
757
} catch (e) {
···
894
894
return;
895
895
}
896
896
const stats = await statsRes.json();
897
-
const userAgents = await uaRes.json();
897
+
const uaData = await uaRes.json();
898
898
const referers = await refRes.json();
899
899
900
900
document.getElementById('totalRequests').textContent = formatNumber(stats.totalRequests || 0);
901
901
document.getElementById('avgResponseTime').textContent = formatMs(stats.averageResponseTime);
902
902
document.getElementById('uptime').textContent = stats.uptime ? `${stats.uptime.toFixed(1)}%` : '-';
903
-
document.getElementById('uniqueAgents').textContent = formatNumber(userAgents.length || 0);
903
+
document.getElementById('uniqueAgents').textContent = formatNumber(uaData.totalCount || 0);
904
904
905
905
currentTrafficData = trafficData;
906
906
initChart(trafficData);
907
-
allUserAgents = userAgents;
908
-
renderTrafficSources(userAgents, referers);
907
+
allUserAgents = uaData.userAgents;
908
+
renderTrafficSources(uaData.userAgents, referers);
909
909
updateLastUpdated();
910
910
showLoading(false);
911
911
});
+5
-2
src/handlers/index.ts
+5
-2
src/handlers/index.ts
···
309
309
_request,
310
310
recordAnalytics,
311
311
) => {
312
-
const userAgents = await cache.getUserAgents();
312
+
const [userAgents, totalCount] = await Promise.all([
313
+
cache.getUserAgents(),
314
+
cache.getUserAgentCount(),
315
+
]);
313
316
await recordAnalytics(200);
314
-
return Response.json(userAgents);
317
+
return Response.json({ userAgents, totalCount });
315
318
};
316
319
317
320
export const handleGetReferers: RouteHandlerWithAnalytics = async (
+13
-7
src/routes/api-routes.ts
+13
-7
src/routes/api-routes.ts
···
418
418
{
419
419
summary: "Get user agents statistics",
420
420
description:
421
-
"Cumulative list of user agents accessing the service with hit counts",
421
+
"Cumulative list of user agents accessing the service with hit counts (top 50) and total unique count",
422
422
tags: ["Analytics"],
423
423
responses: Object.fromEntries([
424
424
apiResponse(200, "User agents data retrieved successfully", {
425
-
type: "array",
426
-
items: {
427
-
type: "object",
428
-
properties: {
429
-
userAgent: { type: "string", example: "Mozilla/5.0..." },
430
-
hits: { type: "number", example: 123 },
425
+
type: "object",
426
+
properties: {
427
+
userAgents: {
428
+
type: "array",
429
+
items: {
430
+
type: "object",
431
+
properties: {
432
+
userAgent: { type: "string", example: "Mozilla/5.0..." },
433
+
hits: { type: "number", example: 123 },
434
+
},
435
+
},
431
436
},
437
+
totalCount: { type: "number", example: 150 },
432
438
},
433
439
}),
434
440
]),